aboutsummaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APFloat.h1
-rw-r--r--include/llvm/ADT/APInt.h50
-rw-r--r--include/llvm/ADT/APSInt.h48
-rw-r--r--include/llvm/ADT/ArrayRef.h2
-rw-r--r--include/llvm/ADT/BitVector.h56
-rw-r--r--include/llvm/ADT/DenseMap.h882
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h2
-rw-r--r--include/llvm/ADT/FoldingSet.h105
-rw-r--r--include/llvm/ADT/Hashing.h4
-rw-r--r--include/llvm/ADT/ImmutableSet.h4
-rw-r--r--include/llvm/ADT/IndexedMap.h9
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h34
-rw-r--r--include/llvm/ADT/PointerIntPair.h13
-rw-r--r--include/llvm/ADT/PointerUnion.h4
-rw-r--r--include/llvm/ADT/PostOrderIterator.h75
-rw-r--r--include/llvm/ADT/STLExtras.h22
-rw-r--r--include/llvm/ADT/SmallBitVector.h83
-rw-r--r--include/llvm/ADT/SmallString.h7
-rw-r--r--include/llvm/ADT/SmallVector.h298
-rw-r--r--include/llvm/ADT/SparseSet.h112
-rw-r--r--include/llvm/ADT/StringRef.h29
-rw-r--r--include/llvm/ADT/StringSwitch.h4
-rw-r--r--include/llvm/ADT/TinyPtrVector.h184
-rw-r--r--include/llvm/ADT/Triple.h14
-rw-r--r--include/llvm/ADT/ValueMap.h22
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h13
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h2
-rw-r--r--include/llvm/Analysis/CodeMetrics.h8
-rw-r--r--include/llvm/Analysis/Dominators.h8
-rw-r--r--include/llvm/Analysis/InlineCost.h4
-rw-r--r--include/llvm/Analysis/LoopInfo.h485
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h570
-rw-r--r--include/llvm/Analysis/LoopIterator.h42
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h189
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h7
-rw-r--r--include/llvm/Analysis/ProfileInfoLoader.h5
-rw-r--r--include/llvm/Analysis/RegionInfo.h80
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h8
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h6
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h69
-rw-r--r--include/llvm/Analysis/ValueTracking.h8
-rw-r--r--include/llvm/Attributes.h73
-rw-r--r--include/llvm/Bitcode/Archive.h22
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h18
-rw-r--r--include/llvm/CMakeLists.txt2
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h7
-rw-r--r--include/llvm/CodeGen/DFAPacketizer.h44
-rw-r--r--include/llvm/CodeGen/EdgeBundles.h2
-rw-r--r--include/llvm/CodeGen/FastISel.h14
-rw-r--r--include/llvm/CodeGen/GCMetadata.h19
-rw-r--r--include/llvm/CodeGen/GCStrategy.h16
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h591
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h7
-rw-r--r--include/llvm/CodeGen/LiveInterval.h189
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h230
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h55
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h77
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h16
-rw-r--r--include/llvm/CodeGen/MachineFunction.h4
-rw-r--r--include/llvm/CodeGen/MachineInstr.h28
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h13
-rw-r--r--include/llvm/CodeGen/MachineInstrBundle.h4
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h20
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineOperand.h66
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h17
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h93
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h11
-rw-r--r--include/llvm/CodeGen/Passes.h80
-rw-r--r--include/llvm/CodeGen/ProcessImplicitDefs.h51
-rw-r--r--include/llvm/CodeGen/RegisterClassInfo.h132
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h282
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h24
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h28
-rw-r--r--include/llvm/CodeGen/ScheduleHazardRecognizer.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h77
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h37
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h27
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h49
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h3
-rw-r--r--include/llvm/CodeGen/ValueTypes.h120
-rw-r--r--include/llvm/CodeGen/ValueTypes.td30
-rw-r--r--include/llvm/Config/config.h.cmake29
-rw-r--r--include/llvm/Config/config.h.in11
-rw-r--r--include/llvm/Config/llvm-config.h.cmake3
-rw-r--r--include/llvm/Config/llvm-config.h.in3
-rw-r--r--include/llvm/Constant.h4
-rw-r--r--include/llvm/Constants.h11
-rw-r--r--include/llvm/DIBuilder.h (renamed from include/llvm/Analysis/DIBuilder.h)28
-rw-r--r--include/llvm/DebugInfo.h (renamed from include/llvm/Analysis/DebugInfo.h)110
-rw-r--r--include/llvm/DebugInfo/DIContext.h42
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h2
-rw-r--r--include/llvm/ExecutionEngine/Interpreter.h2
-rw-r--r--include/llvm/ExecutionEngine/JIT.h2
-rw-r--r--include/llvm/ExecutionEngine/MCJIT.h2
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h11
-rw-r--r--include/llvm/Function.h4
-rw-r--r--include/llvm/GlobalValue.h10
-rw-r--r--include/llvm/GlobalVariable.h29
-rw-r--r--include/llvm/IRBuilder.h (renamed from include/llvm/Support/IRBuilder.h)29
-rw-r--r--include/llvm/InitializePasses.h7
-rw-r--r--include/llvm/Instruction.h33
-rw-r--r--include/llvm/Instructions.h397
-rw-r--r--include/llvm/Intrinsics.h47
-rw-r--r--include/llvm/Intrinsics.td32
-rw-r--r--include/llvm/IntrinsicsHexagon.td2978
-rw-r--r--include/llvm/IntrinsicsMips.td264
-rw-r--r--include/llvm/IntrinsicsNVVM.td952
-rw-r--r--include/llvm/IntrinsicsPTX.td92
-rw-r--r--include/llvm/IntrinsicsX86.td518
-rw-r--r--include/llvm/LinkAllPasses.h1
-rw-r--r--include/llvm/MC/EDInstInfo.h4
-rw-r--r--include/llvm/MC/MCAsmInfo.h59
-rw-r--r--include/llvm/MC/MCAssembler.h44
-rw-r--r--include/llvm/MC/MCContext.h4
-rw-r--r--include/llvm/MC/MCDirectives.h8
-rw-r--r--include/llvm/MC/MCDisassembler.h12
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h44
-rw-r--r--include/llvm/MC/MCExpr.h6
-rw-r--r--include/llvm/MC/MCFixupKindInfo.h2
-rw-r--r--include/llvm/MC/MCInstrItineraries.h46
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h3
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h24
-rw-r--r--include/llvm/MC/MCObjectWriter.h5
-rw-r--r--include/llvm/MC/MCRegisterInfo.h303
-rw-r--r--include/llvm/MC/MCSchedule.h114
-rw-r--r--include/llvm/MC/MCStreamer.h57
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h15
-rw-r--r--include/llvm/MC/MCTargetAsmLexer.h34
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h13
-rw-r--r--include/llvm/MC/MachineLocation.h10
-rw-r--r--include/llvm/MC/SubtargetFeature.h22
-rw-r--r--include/llvm/MDBuilder.h (renamed from include/llvm/Support/MDBuilder.h)29
-rw-r--r--include/llvm/Metadata.h5
-rw-r--r--include/llvm/Module.h11
-rw-r--r--include/llvm/Object/Binary.h2
-rw-r--r--include/llvm/Object/COFF.h6
-rw-r--r--include/llvm/Object/ELF.h145
-rw-r--r--include/llvm/Object/MachOFormat.h18
-rw-r--r--include/llvm/Object/MachOObject.h3
-rw-r--r--include/llvm/Object/ObjectFile.h11
-rw-r--r--include/llvm/PassManagers.h3
-rw-r--r--include/llvm/Support/AlignOf.h92
-rw-r--r--include/llvm/Support/COFF.h10
-rw-r--r--include/llvm/Support/CallSite.h5
-rw-r--r--include/llvm/Support/CommandLine.h8
-rw-r--r--include/llvm/Support/Compiler.h21
-rw-r--r--include/llvm/Support/ConstantRange.h4
-rw-r--r--include/llvm/Support/DataTypes.h.cmake12
-rw-r--r--include/llvm/Support/DataTypes.h.in12
-rw-r--r--include/llvm/Support/Debug.h8
-rw-r--r--include/llvm/Support/DebugLoc.h9
-rw-r--r--include/llvm/Support/ELF.h130
-rw-r--r--include/llvm/Support/Endian.h8
-rw-r--r--include/llvm/Support/FileOutputBuffer.h97
-rw-r--r--include/llvm/Support/FileSystem.h109
-rw-r--r--include/llvm/Support/GCOV.h20
-rw-r--r--include/llvm/Support/GraphWriter.h4
-rw-r--r--include/llvm/Support/InstVisitor.h53
-rw-r--r--include/llvm/Support/IntegersSubset.h541
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h580
-rw-r--r--include/llvm/Support/LEB128.h58
-rw-r--r--include/llvm/Support/MachO.h82
-rw-r--r--include/llvm/Support/MathExtras.h4
-rw-r--r--include/llvm/Support/PathV2.h6
-rw-r--r--include/llvm/Support/Process.h10
-rw-r--r--include/llvm/Support/SMLoc.h3
-rw-r--r--include/llvm/Support/SourceMgr.h13
-rw-r--r--include/llvm/Support/TargetRegistry.h20
-rw-r--r--include/llvm/Support/ThreadLocal.h11
-rw-r--r--include/llvm/Support/ValueHandle.h11
-rw-r--r--include/llvm/Support/YAMLParser.h33
-rw-r--r--include/llvm/Support/raw_ostream.h7
-rw-r--r--include/llvm/Support/type_traits.h15
-rw-r--r--include/llvm/TableGen/Record.h10
-rw-r--r--include/llvm/TableGen/StringMatcher.h54
-rw-r--r--include/llvm/TableGen/TableGenBackend.h28
-rw-r--r--include/llvm/Target/Target.td74
-rw-r--r--include/llvm/Target/TargetCallingConv.h6
-rw-r--r--include/llvm/Target/TargetData.h8
-rw-r--r--include/llvm/Target/TargetELFWriterInfo.h3
-rw-r--r--include/llvm/Target/TargetInstrInfo.h188
-rw-r--r--include/llvm/Target/TargetItinerary.td136
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h187
-rw-r--r--include/llvm/Target/TargetLowering.h152
-rw-r--r--include/llvm/Target/TargetMachine.h9
-rw-r--r--include/llvm/Target/TargetOptions.h51
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h189
-rw-r--r--include/llvm/Target/TargetSchedule.td131
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td12
-rw-r--r--include/llvm/Transforms/Instrumentation.h7
-rw-r--r--include/llvm/Transforms/Scalar.h5
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h4
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h49
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h127
-rw-r--r--include/llvm/Transforms/Utils/FunctionUtils.h45
-rw-r--r--include/llvm/Transforms/Utils/Local.h64
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h1
-rw-r--r--include/llvm/Transforms/Vectorize.h9
-rw-r--r--include/llvm/TypeBuilder.h (renamed from include/llvm/Support/TypeBuilder.h)6
-rw-r--r--include/llvm/TypeFinder.h78
-rw-r--r--include/llvm/User.h4
202 files changed, 12161 insertions, 4351 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 2b466f900c81..5a625a4c832f 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -274,6 +274,7 @@ namespace llvm {
/* C fmod, or llvm frem. */
opStatus mod(const APFloat &, roundingMode);
opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
+ opStatus roundToIntegral(roundingMode);
/* Sign operations. */
void changeSign();
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 41019899766b..f30a6e3f081c 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -16,6 +16,7 @@
#define LLVM_APINT_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <climits>
@@ -273,6 +274,13 @@ public:
initSlowCase(that);
}
+#if LLVM_USE_RVALUE_REFERENCES
+ /// @brief Move Constructor.
+ APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
+ that.BitWidth = 0;
+ }
+#endif
+
/// @brief Destructor.
~APInt() {
if (!isSingleWord())
@@ -349,13 +357,7 @@ public:
/// @brief Check if this APInt has an N-bits unsigned integer value.
bool isIntN(unsigned N) const {
assert(N && "N == 0 ???");
- if (N >= getBitWidth())
- return true;
-
- if (isSingleWord())
- return isUIntN(N, VAL);
- return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth())
- == (*this);
+ return getActiveBits() <= N;
}
/// @brief Check if this APInt has an N-bits signed integer value.
@@ -503,6 +505,18 @@ public:
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
+ /// \brief Determine if two APInts have the same value, after zero-extending
+ /// one of them (if needed!) to ensure that the bit-widths match.
+ static bool isSameValue(const APInt &I1, const APInt &I2) {
+ if (I1.getBitWidth() == I2.getBitWidth())
+ return I1 == I2;
+
+ if (I1.getBitWidth() > I2.getBitWidth())
+ return I1 == I2.zext(I1.getBitWidth());
+
+ return I1.zext(I2.getBitWidth()) == I2;
+ }
+
/// \brief Overload to compute a hash_code for an APInt value.
friend hash_code hash_value(const APInt &Arg);
@@ -587,6 +601,21 @@ public:
return AssignSlowCase(RHS);
}
+#if LLVM_USE_RVALUE_REFERENCES
+ /// @brief Move assignment operator.
+ APInt& operator=(APInt&& that) {
+ if (!isSingleWord())
+ delete [] pVal;
+
+ BitWidth = that.BitWidth;
+ VAL = that.VAL;
+
+ that.BitWidth = 0;
+
+ return *this;
+ }
+#endif
+
/// The RHS value is assigned to *this. If the significant bits in RHS exceed
/// the bit width, the excess bits are truncated. If the bit width is larger
/// than 64, the value is zero filled in the unspecified high order bits.
@@ -817,9 +846,10 @@ public:
if (LHS.isNegative()) {
if (RHS.isNegative())
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
- else
+ else {
APInt::udivrem(-LHS, RHS, Quotient, Remainder);
- Quotient = -Quotient;
+ Quotient = -Quotient;
+ }
Remainder = -Remainder;
} else if (RHS.isNegative()) {
APInt::udivrem(LHS, -RHS, Quotient, Remainder);
@@ -1087,7 +1117,7 @@ public:
else {
// Set all the bits in all the words.
for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] = -1ULL;
+ pVal[i] = -1ULL;
}
// Clear the unused ones
clearUnusedBits();
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 54a7b601d1f1..048c65ce2c77 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -135,6 +135,19 @@ public:
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return IsUnsigned ? uge(RHS) : sge(RHS);
}
+ inline bool operator==(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return eq(RHS);
+ }
+ inline bool operator==(int64_t RHS) const {
+ return isSameValue(*this, APSInt(APInt(64, RHS), true));
+ }
+ inline bool operator!=(const APSInt& RHS) const {
+ return !((*this) == RHS);
+ }
+ inline bool operator!=(int64_t RHS) const {
+ return !((*this) == RHS);
+ }
// The remaining operators just wrap the logic of APInt, but retain the
// signedness information.
@@ -250,17 +263,50 @@ public:
: APInt::getSignedMinValue(numBits), Unsigned);
}
+ /// \brief Determine if two APSInts have the same value, zero- or
+ /// sign-extending as needed.
+ static bool isSameValue(const APSInt &I1, const APSInt &I2) {
+ if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
+ return I1 == I2;
+
+ // Check for a bit-width mismatch.
+ if (I1.getBitWidth() > I2.getBitWidth())
+ return isSameValue(I1, I2.extend(I1.getBitWidth()));
+ else if (I2.getBitWidth() > I1.getBitWidth())
+ return isSameValue(I1.extend(I2.getBitWidth()), I2);
+
+ // We have a signedness mismatch. Turn the signed value into an unsigned
+ // value.
+ if (I1.isSigned()) {
+ if (I1.isNegative())
+ return false;
+
+ return APSInt(I1, true) == I2;
+ }
+
+ if (I2.isNegative())
+ return false;
+
+ return I1 == APSInt(I2, true);
+ }
+
/// Profile - Used to insert APSInt objects, or objects that contain APSInt
/// objects, into FoldingSets.
void Profile(FoldingSetNodeID& ID) const;
};
+inline bool operator==(int64_t V1, const APSInt& V2) {
+ return V2 == V1;
+}
+inline bool operator!=(int64_t V1, const APSInt& V2) {
+ return V2 != V1;
+}
+
inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
I.print(OS, I.isSigned());
return OS;
}
-
} // end namespace llvm
#endif
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index f4c8e5586213..cf55aadef31a 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -60,7 +60,7 @@ namespace llvm {
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector.
- /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
+ /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a std::vector.
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 7e0b5ba37196..3e2e5f230a3a 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_BITVECTOR_H
#define LLVM_ADT_BITVECTOR_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
@@ -97,6 +98,13 @@ public:
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
+#if LLVM_USE_RVALUE_REFERENCES
+ BitVector(BitVector &&RHS)
+ : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
+ RHS.Bits = 0;
+ }
+#endif
+
~BitVector() {
std::free(Bits);
}
@@ -251,11 +259,6 @@ public:
return *this;
}
- // No argument flip.
- BitVector operator~() const {
- return BitVector(*this).flip();
- }
-
// Indexing.
reference operator[](unsigned Idx) {
assert (Idx < Size && "Out-of-bounds Bit access.");
@@ -272,6 +275,16 @@ public:
return (*this)[Idx];
}
+ /// Test if any common bits are set.
+ bool anyCommon(const BitVector &RHS) const {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i)
+ if (Bits[i] & RHS.Bits[i])
+ return true;
+ return false;
+ }
+
// Comparison operators.
bool operator==(const BitVector &RHS) const {
unsigned ThisWords = NumBitWords(size());
@@ -366,6 +379,21 @@ public:
return *this;
}
+#if LLVM_USE_RVALUE_REFERENCES
+ const BitVector &operator=(BitVector &&RHS) {
+ if (this == &RHS) return *this;
+
+ std::free(Bits);
+ Bits = RHS.Bits;
+ Size = RHS.Size;
+ Capacity = RHS.Capacity;
+
+ RHS.Bits = 0;
+
+ return *this;
+ }
+#endif
+
void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits);
std::swap(Size, RHS.Size);
@@ -472,24 +500,6 @@ private:
}
};
-inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
- BitVector Result(LHS);
- Result &= RHS;
- return Result;
-}
-
-inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
- BitVector Result(LHS);
- Result |= RHS;
- return Result;
-}
-
-inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
- BitVector Result(LHS);
- Result ^= RHS;
- return Result;
-}
-
} // End llvm namespace
namespace std {
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 8d4a19d0919c..65a70fbfa6d0 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -14,6 +14,8 @@
#ifndef LLVM_ADT_DENSEMAP_H
#define LLVM_ADT_DENSEMAP_H
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
@@ -23,6 +25,7 @@
#include <new>
#include <utility>
#include <cassert>
+#include <climits>
#include <cstddef>
#include <cstring>
@@ -33,116 +36,83 @@ template<typename KeyT, typename ValueT,
bool IsConst = false>
class DenseMapIterator;
-template<typename KeyT, typename ValueT,
- typename KeyInfoT = DenseMapInfo<KeyT> >
-class DenseMap {
+template<typename DerivedT,
+ typename KeyT, typename ValueT, typename KeyInfoT>
+class DenseMapBase {
+protected:
typedef std::pair<KeyT, ValueT> BucketT;
- unsigned NumBuckets;
- BucketT *Buckets;
- unsigned NumEntries;
- unsigned NumTombstones;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;
typedef BucketT value_type;
- DenseMap(const DenseMap &other) {
- NumBuckets = 0;
- CopyFrom(other);
- }
-
- explicit DenseMap(unsigned NumInitBuckets = 0) {
- init(NumInitBuckets);
- }
-
- template<typename InputIt>
- DenseMap(const InputIt &I, const InputIt &E) {
- init(NextPowerOf2(std::distance(I, E)));
- insert(I, E);
- }
-
- ~DenseMap() {
- const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
- for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
- if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
- !KeyInfoT::isEqual(P->first, TombstoneKey))
- P->second.~ValueT();
- P->first.~KeyT();
- }
-#ifndef NDEBUG
- if (NumBuckets)
- memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
-#endif
- operator delete(Buckets);
- }
-
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
typedef DenseMapIterator<KeyT, ValueT,
KeyInfoT, true> const_iterator;
inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
- return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
+ return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
}
inline iterator end() {
- return iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
+ return iterator(getBucketsEnd(), getBucketsEnd(), true);
}
inline const_iterator begin() const {
- return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
+ return empty() ? end() : const_iterator(getBuckets(), getBucketsEnd());
}
inline const_iterator end() const {
- return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
+ return const_iterator(getBucketsEnd(), getBucketsEnd(), true);
}
- bool empty() const { return NumEntries == 0; }
- unsigned size() const { return NumEntries; }
+ bool empty() const { return getNumEntries() == 0; }
+ unsigned size() const { return getNumEntries(); }
/// Grow the densemap so that it has at least Size buckets. Does not shrink
void resize(size_t Size) {
- if (Size > NumBuckets)
+ if (Size > getNumBuckets())
grow(Size);
}
void clear() {
- if (NumEntries == 0 && NumTombstones == 0) return;
+ if (getNumEntries() == 0 && getNumTombstones() == 0) return;
// If the capacity of the array is huge, and the # elements used is small,
// shrink the array.
- if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
+ if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
shrink_and_clear();
return;
}
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
- for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
P->second.~ValueT();
- --NumEntries;
+ decrementNumEntries();
}
P->first = EmptyKey;
}
}
- assert(NumEntries == 0 && "Node count imbalance!");
- NumTombstones = 0;
+ assert(getNumEntries() == 0 && "Node count imbalance!");
+ setNumTombstones(0);
}
/// count - Return true if the specified key is in the map.
bool count(const KeyT &Val) const {
- BucketT *TheBucket;
+ const BucketT *TheBucket;
return LookupBucketFor(Val, TheBucket);
}
iterator find(const KeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return iterator(TheBucket, Buckets+NumBuckets, true);
+ return iterator(TheBucket, getBucketsEnd(), true);
return end();
}
const_iterator find(const KeyT &Val) const {
- BucketT *TheBucket;
+ const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return const_iterator(TheBucket, Buckets+NumBuckets, true);
+ return const_iterator(TheBucket, getBucketsEnd(), true);
return end();
}
@@ -155,21 +125,21 @@ public:
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return iterator(TheBucket, Buckets+NumBuckets, true);
+ return iterator(TheBucket, getBucketsEnd(), true);
return end();
}
template<class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
- BucketT *TheBucket;
+ const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return const_iterator(TheBucket, Buckets+NumBuckets, true);
+ return const_iterator(TheBucket, getBucketsEnd(), true);
return end();
}
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueT lookup(const KeyT &Val) const {
- BucketT *TheBucket;
+ const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return TheBucket->second;
return ValueT();
@@ -181,12 +151,12 @@ public:
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
BucketT *TheBucket;
if (LookupBucketFor(KV.first, TheBucket))
- return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true),
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
- return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true), true);
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
/// insert - Range insertion of pairs.
@@ -204,23 +174,16 @@ public:
TheBucket->second.~ValueT();
TheBucket->first = getTombstoneKey();
- --NumEntries;
- ++NumTombstones;
+ decrementNumEntries();
+ incrementNumTombstones();
return true;
}
void erase(iterator I) {
BucketT *TheBucket = &*I;
TheBucket->second.~ValueT();
TheBucket->first = getTombstoneKey();
- --NumEntries;
- ++NumTombstones;
- }
-
- void swap(DenseMap& RHS) {
- std::swap(NumBuckets, RHS.NumBuckets);
- std::swap(Buckets, RHS.Buckets);
- std::swap(NumEntries, RHS.NumEntries);
- std::swap(NumTombstones, RHS.NumTombstones);
+ decrementNumEntries();
+ incrementNumTombstones();
}
value_type& FindAndConstruct(const KeyT &Key) {
@@ -235,68 +198,211 @@ public:
return FindAndConstruct(Key).second;
}
- DenseMap& operator=(const DenseMap& other) {
- CopyFrom(other);
- return *this;
+#if LLVM_USE_RVALUE_REFERENCES
+ value_type& FindAndConstruct(KeyT &&Key) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Key, TheBucket))
+ return *TheBucket;
+
+ return *InsertIntoBucket(Key, ValueT(), TheBucket);
}
+ ValueT &operator[](KeyT &&Key) {
+ return FindAndConstruct(Key).second;
+ }
+#endif
+
/// isPointerIntoBucketsArray - Return true if the specified pointer points
/// somewhere into the DenseMap's array of buckets (i.e. either to a key or
/// value in the DenseMap).
bool isPointerIntoBucketsArray(const void *Ptr) const {
- return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
+ return Ptr >= getBuckets() && Ptr < getBucketsEnd();
}
/// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
/// array. In conjunction with the previous method, this can be used to
/// determine whether an insertion caused the DenseMap to reallocate.
- const void *getPointerIntoBucketsArray() const { return Buckets; }
+ const void *getPointerIntoBucketsArray() const { return getBuckets(); }
-private:
- void CopyFrom(const DenseMap& other) {
- if (NumBuckets != 0 &&
- (!isPodLike<KeyT>::value || !isPodLike<ValueT>::value)) {
- const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
- for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
- if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
- !KeyInfoT::isEqual(P->first, TombstoneKey))
- P->second.~ValueT();
- P->first.~KeyT();
- }
- }
+protected:
+ DenseMapBase() {}
- NumEntries = other.NumEntries;
- NumTombstones = other.NumTombstones;
+ void destroyAll() {
+ if (getNumBuckets() == 0) // Nothing to do.
+ return;
+
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
- if (NumBuckets) {
#ifndef NDEBUG
- memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
+ memset((void*)getBuckets(), 0x5a, sizeof(BucketT)*getNumBuckets());
#endif
- operator delete(Buckets);
- }
+ }
- NumBuckets = other.NumBuckets;
+ void initEmpty() {
+ setNumEntries(0);
+ setNumTombstones(0);
- if (NumBuckets == 0) {
- Buckets = 0;
- return;
+ assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
+ "# initial buckets must be a power of two!");
+ const KeyT EmptyKey = getEmptyKey();
+ for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
+ new (&B->first) KeyT(EmptyKey);
+ }
+
+ void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
+ initEmpty();
+
+ // Insert all the old elements.
+ const KeyT EmptyKey = getEmptyKey();
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Insert the key/value into the new table.
+ BucketT *DestBucket;
+ bool FoundVal = LookupBucketFor(B->first, DestBucket);
+ (void)FoundVal; // silence warning.
+ assert(!FoundVal && "Key already in new map?");
+ DestBucket->first = llvm_move(B->first);
+ new (&DestBucket->second) ValueT(llvm_move(B->second));
+ incrementNumEntries();
+
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
}
- Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
+#ifndef NDEBUG
+ if (OldBucketsBegin != OldBucketsEnd)
+ memset((void*)OldBucketsBegin, 0x5a,
+ sizeof(BucketT) * (OldBucketsEnd - OldBucketsBegin));
+#endif
+ }
+
+ template <typename OtherBaseT>
+ void copyFrom(const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT>& other) {
+ assert(getNumBuckets() == other.getNumBuckets());
+
+ setNumEntries(other.getNumEntries());
+ setNumTombstones(other.getNumTombstones());
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
- memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
+ memcpy(getBuckets(), other.getBuckets(),
+ getNumBuckets() * sizeof(BucketT));
else
- for (size_t i = 0; i < NumBuckets; ++i) {
- new (&Buckets[i].first) KeyT(other.Buckets[i].first);
- if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
- !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
- new (&Buckets[i].second) ValueT(other.Buckets[i].second);
+ for (size_t i = 0; i < getNumBuckets(); ++i) {
+ new (&getBuckets()[i].first) KeyT(other.getBuckets()[i].first);
+ if (!KeyInfoT::isEqual(getBuckets()[i].first, getEmptyKey()) &&
+ !KeyInfoT::isEqual(getBuckets()[i].first, getTombstoneKey()))
+ new (&getBuckets()[i].second) ValueT(other.getBuckets()[i].second);
}
}
+ void swap(DenseMapBase& RHS) {
+ std::swap(getNumEntries(), RHS.getNumEntries());
+ std::swap(getNumTombstones(), RHS.getNumTombstones());
+ }
+
+ static unsigned getHashValue(const KeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ template<typename LookupKeyT>
+ static unsigned getHashValue(const LookupKeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ static const KeyT getEmptyKey() {
+ return KeyInfoT::getEmptyKey();
+ }
+ static const KeyT getTombstoneKey() {
+ return KeyInfoT::getTombstoneKey();
+ }
+
+private:
+ unsigned getNumEntries() const {
+ return static_cast<const DerivedT *>(this)->getNumEntries();
+ }
+ void setNumEntries(unsigned Num) {
+ static_cast<DerivedT *>(this)->setNumEntries(Num);
+ }
+ void incrementNumEntries() {
+ setNumEntries(getNumEntries() + 1);
+ }
+ void decrementNumEntries() {
+ setNumEntries(getNumEntries() - 1);
+ }
+ unsigned getNumTombstones() const {
+ return static_cast<const DerivedT *>(this)->getNumTombstones();
+ }
+ void setNumTombstones(unsigned Num) {
+ static_cast<DerivedT *>(this)->setNumTombstones(Num);
+ }
+ void incrementNumTombstones() {
+ setNumTombstones(getNumTombstones() + 1);
+ }
+ void decrementNumTombstones() {
+ setNumTombstones(getNumTombstones() - 1);
+ }
+ const BucketT *getBuckets() const {
+ return static_cast<const DerivedT *>(this)->getBuckets();
+ }
+ BucketT *getBuckets() {
+ return static_cast<DerivedT *>(this)->getBuckets();
+ }
+ unsigned getNumBuckets() const {
+ return static_cast<const DerivedT *>(this)->getNumBuckets();
+ }
+ BucketT *getBucketsEnd() {
+ return getBuckets() + getNumBuckets();
+ }
+ const BucketT *getBucketsEnd() const {
+ return getBuckets() + getNumBuckets();
+ }
+
+ void grow(unsigned AtLeast) {
+ static_cast<DerivedT *>(this)->grow(AtLeast);
+ }
+
+ void shrink_and_clear() {
+ static_cast<DerivedT *>(this)->shrink_and_clear();
+ }
+
+
BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
BucketT *TheBucket) {
+ TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(Value);
+ return TheBucket;
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
+ BucketT *TheBucket) {
+ TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(std::move(Value));
+ return TheBucket;
+ }
+
+ BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
+ TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+ TheBucket->first = std::move(Key);
+ new (&TheBucket->second) ValueT(std::move(Value));
+ return TheBucket;
+ }
+#endif
+
+ BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of
// the buckets are empty (meaning that many are filled with tombstones),
// grow the table.
@@ -306,48 +412,38 @@ private:
// probe almost the entire table until it found the empty bucket. If the
// table completely filled with tombstones, no lookup would ever succeed,
// causing infinite loops in lookup.
- ++NumEntries;
- if (NumEntries*4 >= NumBuckets*3) {
+ unsigned NewNumEntries = getNumEntries() + 1;
+ unsigned NumBuckets = getNumBuckets();
+ if (NewNumEntries*4 >= NumBuckets*3) {
this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket);
+ NumBuckets = getNumBuckets();
}
- if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+ if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
this->grow(NumBuckets);
LookupBucketFor(Key, TheBucket);
}
+ // Only update the state after we've grown our bucket space appropriately
+ // so that when growing buckets we have self-consistent entry count.
+ incrementNumEntries();
+
// If we are writing over a tombstone, remember this.
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
- --NumTombstones;
+ decrementNumTombstones();
- TheBucket->first = Key;
- new (&TheBucket->second) ValueT(Value);
return TheBucket;
}
- static unsigned getHashValue(const KeyT &Val) {
- return KeyInfoT::getHashValue(Val);
- }
- template<typename LookupKeyT>
- static unsigned getHashValue(const LookupKeyT &Val) {
- return KeyInfoT::getHashValue(Val);
- }
- static const KeyT getEmptyKey() {
- return KeyInfoT::getEmptyKey();
- }
- static const KeyT getTombstoneKey() {
- return KeyInfoT::getTombstoneKey();
- }
-
/// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
/// FoundBucket. If the bucket contains the key and a value, this returns
/// true, otherwise it returns a bucket with an empty marker or tombstone and
/// returns false.
template<typename LookupKeyT>
- bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) const {
- unsigned BucketNo = getHashValue(Val);
- unsigned ProbeAmt = 1;
- BucketT *BucketsPtr = Buckets;
+ bool LookupBucketFor(const LookupKeyT &Val,
+ const BucketT *&FoundBucket) const {
+ const BucketT *BucketsPtr = getBuckets();
+ const unsigned NumBuckets = getNumBuckets();
if (NumBuckets == 0) {
FoundBucket = 0;
@@ -355,15 +451,17 @@ private:
}
// FoundTombstone - Keep track of whether we find a tombstone while probing.
- BucketT *FoundTombstone = 0;
+ const BucketT *FoundTombstone = 0;
const KeyT EmptyKey = getEmptyKey();
const KeyT TombstoneKey = getTombstoneKey();
assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
!KeyInfoT::isEqual(Val, TombstoneKey) &&
"Empty/Tombstone value shouldn't be inserted into map!");
+ unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
+ unsigned ProbeAmt = 1;
while (1) {
- BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+ const BucketT *ThisBucket = BucketsPtr + BucketNo;
// Found Val's bucket? If so, return it.
if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
FoundBucket = ThisBucket;
@@ -388,115 +486,481 @@ private:
// Otherwise, it's a hash collision or a tombstone, continue quadratic
// probing.
BucketNo += ProbeAmt++;
+ BucketNo &= (NumBuckets-1);
}
}
- void init(unsigned InitBuckets) {
- NumEntries = 0;
- NumTombstones = 0;
- NumBuckets = InitBuckets;
+ template <typename LookupKeyT>
+ bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
+ const BucketT *ConstFoundBucket;
+ bool Result = const_cast<const DenseMapBase *>(this)
+ ->LookupBucketFor(Val, ConstFoundBucket);
+ FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
+ return Result;
+ }
- if (InitBuckets == 0) {
- Buckets = 0;
- return;
+public:
+ /// Return the approximate size (in bytes) of the actual map.
+ /// This is just the raw memory used by DenseMap.
+ /// If entries are pointers to objects, the size of the referenced objects
+ /// are not included.
+ size_t getMemorySize() const {
+ return getNumBuckets() * sizeof(BucketT);
+ }
+};
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT> >
+class DenseMap
+ : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT>,
+ KeyT, ValueT, KeyInfoT> {
+ // Lift some types from the dependent base class into this class for
+ // simplicity of referring to them.
+ typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT> BaseT;
+ typedef typename BaseT::BucketT BucketT;
+ friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT>;
+
+ BucketT *Buckets;
+ unsigned NumEntries;
+ unsigned NumTombstones;
+ unsigned NumBuckets;
+
+public:
+ explicit DenseMap(unsigned NumInitBuckets = 0) {
+ init(NumInitBuckets);
+ }
+
+ DenseMap(const DenseMap &other) {
+ init(0);
+ copyFrom(other);
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ DenseMap(DenseMap &&other) {
+ init(0);
+ swap(other);
+ }
+#endif
+
+ template<typename InputIt>
+ DenseMap(const InputIt &I, const InputIt &E) {
+ init(NextPowerOf2(std::distance(I, E)));
+ this->insert(I, E);
+ }
+
+ ~DenseMap() {
+ this->destroyAll();
+ operator delete(Buckets);
+ }
+
+ void swap(DenseMap& RHS) {
+ std::swap(Buckets, RHS.Buckets);
+ std::swap(NumEntries, RHS.NumEntries);
+ std::swap(NumTombstones, RHS.NumTombstones);
+ std::swap(NumBuckets, RHS.NumBuckets);
+ }
+
+ DenseMap& operator=(const DenseMap& other) {
+ copyFrom(other);
+ return *this;
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ DenseMap& operator=(DenseMap &&other) {
+ this->destroyAll();
+ operator delete(Buckets);
+ init(0);
+ swap(other);
+ return *this;
+ }
+#endif
+
+ void copyFrom(const DenseMap& other) {
+ this->destroyAll();
+ operator delete(Buckets);
+ if (allocateBuckets(other.NumBuckets)) {
+ this->BaseT::copyFrom(other);
+ } else {
+ NumEntries = 0;
+ NumTombstones = 0;
}
+ }
- assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
- "# initial buckets must be a power of two!");
- Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
- // Initialize all the keys to EmptyKey.
- const KeyT EmptyKey = getEmptyKey();
- for (unsigned i = 0; i != InitBuckets; ++i)
- new (&Buckets[i].first) KeyT(EmptyKey);
+ void init(unsigned InitBuckets) {
+ if (allocateBuckets(InitBuckets)) {
+ this->BaseT::initEmpty();
+ } else {
+ NumEntries = 0;
+ NumTombstones = 0;
+ }
}
void grow(unsigned AtLeast) {
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
- if (NumBuckets < 64)
- NumBuckets = 64;
+ allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast)));
+ assert(Buckets);
+ if (!OldBuckets) {
+ this->BaseT::initEmpty();
+ return;
+ }
- // Double the number of buckets.
- while (NumBuckets < AtLeast)
- NumBuckets <<= 1;
- NumTombstones = 0;
- Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+ this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
- // Initialize all the keys to EmptyKey.
- const KeyT EmptyKey = getEmptyKey();
- for (unsigned i = 0, e = NumBuckets; i != e; ++i)
- new (&Buckets[i].first) KeyT(EmptyKey);
+ // Free the old table.
+ operator delete(OldBuckets);
+ }
- // Insert all the old elements.
- const KeyT TombstoneKey = getTombstoneKey();
- for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
- if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
- !KeyInfoT::isEqual(B->first, TombstoneKey)) {
- // Insert the key/value into the new table.
- BucketT *DestBucket;
- bool FoundVal = LookupBucketFor(B->first, DestBucket);
- (void)FoundVal; // silence warning.
- assert(!FoundVal && "Key already in new map?");
- DestBucket->first = B->first;
- new (&DestBucket->second) ValueT(B->second);
+ void shrink_and_clear() {
+ unsigned OldNumEntries = NumEntries;
+ this->destroyAll();
- // Free the value.
- B->second.~ValueT();
- }
- B->first.~KeyT();
+ // Reduce the number of buckets.
+ unsigned NewNumBuckets = 0;
+ if (OldNumEntries)
+ NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
+ if (NewNumBuckets == NumBuckets) {
+ this->BaseT::initEmpty();
+ return;
}
-#ifndef NDEBUG
- if (OldNumBuckets)
- memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+ operator delete(Buckets);
+ init(NewNumBuckets);
+ }
+
+private:
+ unsigned getNumEntries() const {
+ return NumEntries;
+ }
+ void setNumEntries(unsigned Num) {
+ NumEntries = Num;
+ }
+
+ unsigned getNumTombstones() const {
+ return NumTombstones;
+ }
+ void setNumTombstones(unsigned Num) {
+ NumTombstones = Num;
+ }
+
+ BucketT *getBuckets() const {
+ return Buckets;
+ }
+
+ unsigned getNumBuckets() const {
+ return NumBuckets;
+ }
+
+ bool allocateBuckets(unsigned Num) {
+ NumBuckets = Num;
+ if (NumBuckets == 0) {
+ Buckets = 0;
+ return false;
+ }
+
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
+ return true;
+ }
+};
+
+template<typename KeyT, typename ValueT,
+ unsigned InlineBuckets = 4,
+ typename KeyInfoT = DenseMapInfo<KeyT> >
+class SmallDenseMap
+ : public DenseMapBase<SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT>,
+ KeyT, ValueT, KeyInfoT> {
+ // Lift some types from the dependent base class into this class for
+ // simplicity of referring to them.
+ typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT> BaseT;
+ typedef typename BaseT::BucketT BucketT;
+ friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT>;
+
+ unsigned Small : 1;
+ unsigned NumEntries : 31;
+ unsigned NumTombstones;
+
+ struct LargeRep {
+ BucketT *Buckets;
+ unsigned NumBuckets;
+ };
+
+ /// A "union" of an inline bucket array and the struct representing
+ /// a large bucket. This union will be discriminated by the 'Small' bit.
+ typename AlignedCharArray<BucketT[InlineBuckets], LargeRep>::union_type
+ storage;
+
+public:
+ explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
+ init(NumInitBuckets);
+ }
+
+ SmallDenseMap(const SmallDenseMap &other) {
+ init(0);
+ copyFrom(other);
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallDenseMap(SmallDenseMap &&other) {
+ init(0);
+ swap(other);
+ }
#endif
- // Free the old table.
- operator delete(OldBuckets);
+
+ template<typename InputIt>
+ SmallDenseMap(const InputIt &I, const InputIt &E) {
+ init(NextPowerOf2(std::distance(I, E)));
+ this->insert(I, E);
}
- void shrink_and_clear() {
- unsigned OldNumBuckets = NumBuckets;
- BucketT *OldBuckets = Buckets;
+ ~SmallDenseMap() {
+ this->destroyAll();
+ deallocateBuckets();
+ }
- // Reduce the number of buckets.
- NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
- : 64;
- NumTombstones = 0;
- Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+ void swap(SmallDenseMap& RHS) {
+ unsigned TmpNumEntries = RHS.NumEntries;
+ RHS.NumEntries = NumEntries;
+ NumEntries = TmpNumEntries;
+ std::swap(NumTombstones, RHS.NumTombstones);
- // Initialize all the keys to EmptyKey.
- const KeyT EmptyKey = getEmptyKey();
- for (unsigned i = 0, e = NumBuckets; i != e; ++i)
- new (&Buckets[i].first) KeyT(EmptyKey);
+ const KeyT EmptyKey = this->getEmptyKey();
+ const KeyT TombstoneKey = this->getTombstoneKey();
+ if (Small && RHS.Small) {
+ // If we're swapping inline bucket arrays, we have to cope with some of
+ // the tricky bits of DenseMap's storage system: the buckets are not
+ // fully initialized. Thus we swap every key, but we may have
+ // a one-directional move of the value.
+ for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
+ BucketT *LHSB = &getInlineBuckets()[i],
+ *RHSB = &RHS.getInlineBuckets()[i];
+ bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->first, EmptyKey) &&
+ !KeyInfoT::isEqual(LHSB->first, TombstoneKey));
+ bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->first, EmptyKey) &&
+ !KeyInfoT::isEqual(RHSB->first, TombstoneKey));
+ if (hasLHSValue && hasRHSValue) {
+ // Swap together if we can...
+ std::swap(*LHSB, *RHSB);
+ continue;
+ }
+ // Swap separately and handle any assymetry.
+ std::swap(LHSB->first, RHSB->first);
+ if (hasLHSValue) {
+ new (&RHSB->second) ValueT(llvm_move(LHSB->second));
+ LHSB->second.~ValueT();
+ } else if (hasRHSValue) {
+ new (&LHSB->second) ValueT(llvm_move(RHSB->second));
+ RHSB->second.~ValueT();
+ }
+ }
+ return;
+ }
+ if (!Small && !RHS.Small) {
+ std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
+ std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
+ return;
+ }
- // Free the old buckets.
- const KeyT TombstoneKey = getTombstoneKey();
- for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
- if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
- !KeyInfoT::isEqual(B->first, TombstoneKey)) {
- // Free the value.
- B->second.~ValueT();
+ SmallDenseMap &SmallSide = Small ? *this : RHS;
+ SmallDenseMap &LargeSide = Small ? RHS : *this;
+
+ // First stash the large side's rep and move the small side across.
+ LargeRep TmpRep = llvm_move(*LargeSide.getLargeRep());
+ LargeSide.getLargeRep()->~LargeRep();
+ LargeSide.Small = true;
+ // This is similar to the standard move-from-old-buckets, but the bucket
+ // count hasn't actually rotated in this case. So we have to carefully
+ // move construct the keys and values into their new locations, but there
+ // is no need to re-hash things.
+ for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
+ BucketT *NewB = &LargeSide.getInlineBuckets()[i],
+ *OldB = &SmallSide.getInlineBuckets()[i];
+ new (&NewB->first) KeyT(llvm_move(OldB->first));
+ OldB->first.~KeyT();
+ if (!KeyInfoT::isEqual(NewB->first, EmptyKey) &&
+ !KeyInfoT::isEqual(NewB->first, TombstoneKey)) {
+ new (&NewB->second) ValueT(llvm_move(OldB->second));
+ OldB->second.~ValueT();
}
- B->first.~KeyT();
}
-#ifndef NDEBUG
- memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+ // The hard part of moving the small buckets across is done, just move
+ // the TmpRep into its new home.
+ SmallSide.Small = false;
+ new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep));
+ }
+
+ SmallDenseMap& operator=(const SmallDenseMap& other) {
+ copyFrom(other);
+ return *this;
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallDenseMap& operator=(SmallDenseMap &&other) {
+ this->destroyAll();
+ deallocateBuckets();
+ init(0);
+ swap(other);
+ return *this;
+ }
#endif
+
+ void copyFrom(const SmallDenseMap& other) {
+ this->destroyAll();
+ deallocateBuckets();
+ Small = true;
+ if (other.getNumBuckets() > InlineBuckets) {
+ Small = false;
+ allocateBuckets(other.getNumBuckets());
+ }
+ this->BaseT::copyFrom(other);
+ }
+
+ void init(unsigned InitBuckets) {
+ Small = true;
+ if (InitBuckets > InlineBuckets) {
+ Small = false;
+ new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
+ }
+ this->BaseT::initEmpty();
+ }
+
+ void grow(unsigned AtLeast) {
+ if (AtLeast > InlineBuckets)
+ AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast));
+
+ if (Small) {
+ if (AtLeast <= InlineBuckets)
+ return; // Nothing to do.
+
+ // First move the inline buckets into a temporary storage.
+ typename AlignedCharArray<BucketT[InlineBuckets]>::union_type
+ TmpStorage;
+ BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
+ BucketT *TmpEnd = TmpBegin;
+
+ // Loop over the buckets, moving non-empty, non-tombstones into the
+ // temporary storage. Have the loop move the TmpEnd forward as it goes.
+ const KeyT EmptyKey = this->getEmptyKey();
+ const KeyT TombstoneKey = this->getTombstoneKey();
+ for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey)) {
+ assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
+ "Too many inline buckets!");
+ new (&TmpEnd->first) KeyT(llvm_move(P->first));
+ new (&TmpEnd->second) ValueT(llvm_move(P->second));
+ ++TmpEnd;
+ P->second.~ValueT();
+ }
+ P->first.~KeyT();
+ }
+
+ // Now make this map use the large rep, and move all the entries back
+ // into it.
+ Small = false;
+ new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
+ this->moveFromOldBuckets(TmpBegin, TmpEnd);
+ return;
+ }
+
+ LargeRep OldRep = llvm_move(*getLargeRep());
+ getLargeRep()->~LargeRep();
+ if (AtLeast <= InlineBuckets) {
+ Small = true;
+ } else {
+ new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
+ }
+
+ this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
+
// Free the old table.
- operator delete(OldBuckets);
+ operator delete(OldRep.Buckets);
+ }
+
+ void shrink_and_clear() {
+ unsigned OldSize = this->size();
+ this->destroyAll();
+
+ // Reduce the number of buckets.
+ unsigned NewNumBuckets = 0;
+ if (OldSize) {
+ NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
+ if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
+ NewNumBuckets = 64;
+ }
+ if ((Small && NewNumBuckets <= InlineBuckets) ||
+ (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
+ this->BaseT::initEmpty();
+ return;
+ }
- NumEntries = 0;
+ deallocateBuckets();
+ init(NewNumBuckets);
}
-
-public:
- /// Return the approximate size (in bytes) of the actual map.
- /// This is just the raw memory used by DenseMap.
- /// If entries are pointers to objects, the size of the referenced objects
- /// are not included.
- size_t getMemorySize() const {
- return NumBuckets * sizeof(BucketT);
+
+private:
+ unsigned getNumEntries() const {
+ return NumEntries;
+ }
+ void setNumEntries(unsigned Num) {
+ assert(Num < INT_MAX && "Cannot support more than INT_MAX entries");
+ NumEntries = Num;
+ }
+
+ unsigned getNumTombstones() const {
+ return NumTombstones;
+ }
+ void setNumTombstones(unsigned Num) {
+ NumTombstones = Num;
+ }
+
+ const BucketT *getInlineBuckets() const {
+ assert(Small);
+ // Note that this cast does not violate aliasing rules as we assert that
+ // the memory's dynamic type is the small, inline bucket buffer, and the
+ // 'storage.buffer' static type is 'char *'.
+ return reinterpret_cast<const BucketT *>(storage.buffer);
+ }
+ BucketT *getInlineBuckets() {
+ return const_cast<BucketT *>(
+ const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
+ }
+ const LargeRep *getLargeRep() const {
+ assert(!Small);
+ // Note, same rule about aliasing as with getInlineBuckets.
+ return reinterpret_cast<const LargeRep *>(storage.buffer);
+ }
+ LargeRep *getLargeRep() {
+ return const_cast<LargeRep *>(
+ const_cast<const SmallDenseMap *>(this)->getLargeRep());
+ }
+
+ const BucketT *getBuckets() const {
+ return Small ? getInlineBuckets() : getLargeRep()->Buckets;
+ }
+ BucketT *getBuckets() {
+ return const_cast<BucketT *>(
+ const_cast<const SmallDenseMap *>(this)->getBuckets());
+ }
+ unsigned getNumBuckets() const {
+ return Small ? InlineBuckets : getLargeRep()->NumBuckets;
+ }
+
+ void deallocateBuckets() {
+ if (Small)
+ return;
+
+ operator delete(getLargeRep()->Buckets);
+ getLargeRep()->~LargeRep();
+ }
+
+ LargeRep allocateBuckets(unsigned Num) {
+ assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
+ LargeRep Rep = {
+ static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
+ };
+ return Rep;
}
};
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index dd13a2c02053..519b18052b6d 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -187,7 +187,7 @@ public:
/// current node, counting both nodes.
unsigned getPathLength() const { return VisitStack.size(); }
- /// getPath - Return the n'th node in the path from the the entry node to the
+ /// getPath - Return the n'th node in the path from the entry node to the
/// current node.
NodeType *getPath(unsigned n) const {
return VisitStack[n].first.getPointer();
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 7d7c77770020..ba415ac2d61f 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -518,6 +518,111 @@ public:
};
//===----------------------------------------------------------------------===//
+/// FoldingSetVectorIterator - This implements an iterator for
+/// FoldingSetVector. It is only necessary because FoldingSetIterator provides
+/// a value_type of T, while the vector in FoldingSetVector exposes
+/// a value_type of T*. Fortunately, FoldingSetIterator doesn't expose very
+/// much besides operator* and operator->, so we just wrap the inner vector
+/// iterator and perform the extra dereference.
+template <class T, class VectorIteratorT>
+class FoldingSetVectorIterator {
+ // Provide a typedef to workaround the lack of correct injected class name
+ // support in older GCCs.
+ typedef FoldingSetVectorIterator<T, VectorIteratorT> SelfT;
+
+ VectorIteratorT Iterator;
+
+public:
+ FoldingSetVectorIterator(VectorIteratorT I) : Iterator(I) {}
+
+ bool operator==(const SelfT &RHS) const {
+ return Iterator == RHS.Iterator;
+ }
+ bool operator!=(const SelfT &RHS) const {
+ return Iterator != RHS.Iterator;
+ }
+
+ T &operator*() const { return **Iterator; }
+
+ T *operator->() const { return *Iterator; }
+
+ inline SelfT &operator++() {
+ ++Iterator;
+ return *this;
+ }
+ SelfT operator++(int) {
+ SelfT tmp = *this;
+ ++*this;
+ return tmp;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetVector - This template class combines a FoldingSet and a vector
+/// to provide the interface of FoldingSet but with deterministic iteration
+/// order based on the insertion order. T must be a subclass of FoldingSetNode
+/// and implement a Profile function.
+template <class T, class VectorT = SmallVector<T*, 8> >
+class FoldingSetVector {
+ FoldingSet<T> Set;
+ VectorT Vector;
+
+public:
+ explicit FoldingSetVector(unsigned Log2InitSize = 6)
+ : Set(Log2InitSize) {
+ }
+
+ typedef FoldingSetVectorIterator<T, typename VectorT::iterator> iterator;
+ iterator begin() { return Vector.begin(); }
+ iterator end() { return Vector.end(); }
+
+ typedef FoldingSetVectorIterator<const T, typename VectorT::const_iterator>
+ const_iterator;
+ const_iterator begin() const { return Vector.begin(); }
+ const_iterator end() const { return Vector.end(); }
+
+ /// clear - Remove all nodes from the folding set.
+ void clear() { Set.clear(); Vector.clear(); }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return Set.FindNodeOrInsertPos(ID, InsertPos);
+ }
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and
+ /// return it instead.
+ T *GetOrInsertNode(T *N) {
+ T *Result = Set.GetOrInsertNode(N);
+ if (Result == N) Vector.push_back(N);
+ return Result;
+ }
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set. InsertPos must be obtained from
+ /// FindNodeOrInsertPos.
+ void InsertNode(T *N, void *InsertPos) {
+ Set.InsertNode(N, InsertPos);
+ Vector.push_back(N);
+ }
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set.
+ void InsertNode(T *N) {
+ Set.InsertNode(N);
+ Vector.push_back(N);
+ }
+
+ /// size - Returns the number of nodes in the folding set.
+ unsigned size() const { return Set.size(); }
+
+ /// empty - Returns true if there are no nodes in the folding set.
+ bool empty() const { return Set.empty(); }
+};
+
+//===----------------------------------------------------------------------===//
/// FoldingSetIteratorImpl - This is the common iterator support shared by all
/// folding sets, which knows how to walk the folding set hash table.
class FoldingSetIteratorImpl {
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index 53032ee538d2..6ab07254a21d 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -76,10 +76,6 @@ namespace llvm {
/// using llvm::hash_value;
/// llvm::hash_code code = hash_value(x);
/// \endcode
-///
-/// Also note that there are two numerical values which are reserved, and the
-/// implementation ensures will never be produced for real hash_codes. These
-/// can be used as sentinels within hashing data structures.
class hash_code {
size_t value;
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 89b164819d37..949dc44daba6 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -431,7 +431,7 @@ protected:
// Make sure the index is not the Tombstone or Entry key of the DenseMap.
static inline unsigned maskCacheIndex(unsigned I) {
- return (I & ~0x02);
+ return (I & ~0x02);
}
unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
@@ -667,7 +667,7 @@ public:
return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
}
- uintptr_t getVisitState() {
+ uintptr_t getVisitState() const {
assert(!stack.empty());
return stack.back() & Flags;
}
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
index 87126ea49187..2ffb5058e5bb 100644
--- a/include/llvm/ADT/IndexedMap.h
+++ b/include/llvm/ADT/IndexedMap.h
@@ -20,19 +20,14 @@
#ifndef LLVM_ADT_INDEXEDMAP_H
#define LLVM_ADT_INDEXEDMAP_H
+#include "llvm/ADT/STLExtras.h"
#include <cassert>
#include <functional>
#include <vector>
namespace llvm {
- struct IdentityFunctor : public std::unary_function<unsigned, unsigned> {
- unsigned operator()(unsigned Index) const {
- return Index;
- }
- };
-
- template <typename T, typename ToIndexT = IdentityFunctor>
+template <typename T, typename ToIndexT = llvm::identity<unsigned> >
class IndexedMap {
typedef typename ToIndexT::argument_type IndexT;
typedef std::vector<T> StorageT;
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 3a1a3f4634cf..a9724ee15447 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -21,9 +21,9 @@
#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
-#include <cassert>
-
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include <memory>
namespace llvm {
@@ -34,7 +34,7 @@ namespace llvm {
/// RefCountedBase - A generic base class for objects that wish to
/// have their lifetimes managed using reference counts. Classes
/// subclass RefCountedBase to obtain such functionality, and are
-/// typically handled with IntrusivePtr "smart pointers" (see below)
+/// typically handled with IntrusiveRefCntPtr "smart pointers" (see below)
/// which automatically handle the management of reference counts.
/// Objects that subclass RefCountedBase should not be allocated on
/// the stack, as invoking "delete" (which is called when the
@@ -123,25 +123,25 @@ namespace llvm {
retain();
}
- template <class X>
- IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
- : Obj(S.getPtr()) {
- retain();
+#if LLVM_USE_RVALUE_REFERENCES
+ IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
+ S.Obj = 0;
}
- IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) {
- replace(S.getPtr());
- return *this;
+ template <class X>
+ IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) {
+ S.Obj = 0;
}
+#endif
template <class X>
- IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr<X>& S) {
- replace(S.getPtr());
- return *this;
+ IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
+ : Obj(S.getPtr()) {
+ retain();
}
- IntrusiveRefCntPtr& operator=(T * S) {
- replace(S);
+ IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr S) {
+ swap(S);
return *this;
}
@@ -176,10 +176,6 @@ namespace llvm {
private:
void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
-
- void replace(T* S) {
- this_type(S).swap(*this);
- }
};
template<class T, class U>
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index ccdcd1a8d1b9..fcc758b43a27 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -108,7 +108,14 @@ public:
static PointerIntPair getFromOpaqueValue(void *V) {
PointerIntPair P; P.setFromOpaqueValue(V); return P;
}
-
+
+ // Allow PointerIntPairs to be created from const void * if and only if the
+ // pointer type could be created from a const void *.
+ static PointerIntPair getFromOpaqueValue(const void *V) {
+ (void)PtrTraits::getFromVoidPointer(V);
+ return getFromOpaqueValue(const_cast<void *>(V));
+ }
+
bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
@@ -158,6 +165,10 @@ public:
getFromVoidPointer(void *P) {
return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
}
+ static inline PointerIntPair<PointerTy, IntBits, IntType>
+ getFromVoidPointer(const void *P) {
+ return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
+ }
enum {
NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
};
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 614b59c844e3..a9e86d22002d 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -54,8 +54,8 @@ namespace llvm {
static inline void *getAsVoidPointer(void *P) { return P; }
static inline void *getFromVoidPointer(void *P) { return P; }
enum {
- PT1BitsAv = PointerLikeTypeTraits<PT1>::NumLowBitsAvailable,
- PT2BitsAv = PointerLikeTypeTraits<PT2>::NumLowBitsAvailable,
+ PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
+ PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
};
};
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index 63a2b5219f73..7f6350e4443e 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -23,26 +23,65 @@
namespace llvm {
-template<class SetType, bool External> // Non-external set
+// The po_iterator_storage template provides access to the set of already
+// visited nodes during the po_iterator's depth-first traversal.
+//
+// The default implementation simply contains a set of visited nodes, while
+// the Extended=true version uses a reference to an external set.
+//
+// It is possible to prune the depth-first traversal in several ways:
+//
+// - When providing an external set that already contains some graph nodes,
+// those nodes won't be visited again. This is useful for restarting a
+// post-order traversal on a graph with nodes that aren't dominated by a
+// single node.
+//
+// - By providing a custom SetType class, unwanted graph nodes can be excluded
+// by having the insert() function return false. This could for example
+// confine a CFG traversal to blocks in a specific loop.
+//
+// - Finally, by specializing the po_iterator_storage template itself, graph
+// edges can be pruned by returning false in the insertEdge() function. This
+// could be used to remove loop back-edges from the CFG seen by po_iterator.
+//
+// A specialized po_iterator_storage class can observe both the pre-order and
+// the post-order. The insertEdge() function is called in a pre-order, while
+// the finishPostorder() function is called just before the po_iterator moves
+// on to the next node.
+
+/// Default po_iterator_storage implementation with an internal set object.
+template<class SetType, bool External>
class po_iterator_storage {
-public:
SetType Visited;
-};
+public:
+ // Return true if edge destination should be visited.
+ template<typename NodeType>
+ bool insertEdge(NodeType *From, NodeType *To) {
+ return Visited.insert(To);
+ }
-/// DFSetTraits - Allow the SetType used to record depth-first search results to
-/// optionally record node postorder.
-template<class SetType>
-struct DFSetTraits {
- static void finishPostorder(
- typename SetType::iterator::value_type, SetType &) {}
+ // Called after all children of BB have been visited.
+ template<typename NodeType>
+ void finishPostorder(NodeType *BB) {}
};
+/// Specialization of po_iterator_storage that references an external set.
template<class SetType>
class po_iterator_storage<SetType, true> {
+ SetType &Visited;
public:
po_iterator_storage(SetType &VSet) : Visited(VSet) {}
po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
- SetType &Visited;
+
+ // Return true if edge destination should be visited, called with From = 0 for
+ // the root node.
+ // Graph edges can be pruned by specializing this function.
+ template<class NodeType>
+ bool insertEdge(NodeType *From, NodeType *To) { return Visited.insert(To); }
+
+ // Called after all children of BB have been visited.
+ template<class NodeType>
+ void finishPostorder(NodeType *BB) {}
};
template<class GraphT,
@@ -64,14 +103,15 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
void traverseChild() {
while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
NodeType *BB = *VisitStack.back().second++;
- if (this->Visited.insert(BB)) { // If the block is not visited...
+ if (this->insertEdge(VisitStack.back().first, BB)) {
+ // If the block is not visited...
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
}
}
}
inline po_iterator(NodeType *BB) {
- this->Visited.insert(BB);
+ this->insertEdge((NodeType*)0, BB);
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
@@ -79,7 +119,7 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
inline po_iterator(NodeType *BB, SetType &S) :
po_iterator_storage<SetType, ExtStorage>(S) {
- if (this->Visited.insert(BB)) {
+ if (this->insertEdge((NodeType*)0, BB)) {
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
@@ -117,8 +157,7 @@ public:
inline NodeType *operator->() const { return operator*(); }
inline _Self& operator++() { // Preincrement
- DFSetTraits<SetType>::finishPostorder(VisitStack.back().first,
- this->Visited);
+ this->finishPostorder(VisitStack.back().first);
VisitStack.pop_back();
if (!VisitStack.empty())
traverseChild();
@@ -173,14 +212,14 @@ ipo_iterator<T> ipo_end(T G){
return ipo_iterator<T>::end(G);
}
-//Provide global definitions of external inverse postorder iterators...
+// Provide global definitions of external inverse postorder iterators...
template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*> >
struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
- ipo_iterator<T, SetType, true>(&V) {}
+ ipo_iterator<T, SetType, true>(V) {}
ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
- ipo_iterator<T, SetType, true>(&V) {}
+ ipo_iterator<T, SetType, true>(V) {}
};
template <class T, class SetType>
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index 5da906dc8cf0..aee500d4fb6c 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -30,6 +30,16 @@ namespace llvm {
//===----------------------------------------------------------------------===//
template<class Ty>
+struct identity : public std::unary_function<Ty, Ty> {
+ Ty &operator()(Ty &self) const {
+ return self;
+ }
+ const Ty &operator()(const Ty &self) const {
+ return self;
+ }
+};
+
+template<class Ty>
struct less_ptr : public std::binary_function<Ty, Ty, bool> {
bool operator()(const Ty* left, const Ty* right) const {
return *left < *right;
@@ -49,7 +59,7 @@ struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
// for_each(V.begin(), B.end(), deleter<Interval>);
//
template <class T>
-static inline void deleter(T *Ptr) {
+inline void deleter(T *Ptr) {
delete Ptr;
}
@@ -228,7 +238,7 @@ inline size_t array_lengthof(T (&)[N]) {
/// array_pod_sort_comparator - This is helper function for array_pod_sort,
/// which just uses operator< on T.
template<typename T>
-static 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))
return -1;
if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1))
@@ -239,7 +249,7 @@ static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
/// get_array_pad_sort_comparator - This is an internal helper function used to
/// get type deduction of T right.
template<typename T>
-static int (*get_array_pad_sort_comparator(const T &))
+inline int (*get_array_pad_sort_comparator(const T &))
(const void*, const void*) {
return array_pod_sort_comparator<T>;
}
@@ -260,7 +270,7 @@ static int (*get_array_pad_sort_comparator(const T &))
/// NOTE: If qsort_r were portable, we could allow a custom comparator and
/// default to std::less.
template<class IteratorTy>
-static 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.
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start),
@@ -268,13 +278,13 @@ static inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
}
template<class IteratorTy>
-static inline void array_pod_sort(IteratorTy Start, IteratorTy End,
+inline void array_pod_sort(IteratorTy Start, IteratorTy End,
int (*Compare)(const void*, const void*)) {
// Don't dereference start iterator of empty sequence.
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start), Compare);
}
-
+
//===----------------------------------------------------------------------===//
// Extra additions to <algorithm>
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index a3469a1c6226..7a645e0c7241 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -15,6 +15,7 @@
#define LLVM_ADT_SMALLBITVECTOR_H
#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
@@ -152,6 +153,12 @@ public:
switchToLarge(new BitVector(*RHS.getPointer()));
}
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
+ RHS.X = 1;
+ }
+#endif
+
~SmallBitVector() {
if (!isSmall())
delete getPointer();
@@ -347,6 +354,19 @@ public:
return (*this)[Idx];
}
+ /// Test if any common bits are set.
+ bool anyCommon(const SmallBitVector &RHS) const {
+ if (isSmall() && RHS.isSmall())
+ return (getSmallBits() & RHS.getSmallBits()) != 0;
+ if (!isSmall() && !RHS.isSmall())
+ return getPointer()->anyCommon(*RHS.getPointer());
+
+ for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+ if (test(i) && RHS.test(i))
+ return true;
+ return false;
+ }
+
// Comparison operators.
bool operator==(const SmallBitVector &RHS) const {
if (size() != RHS.size())
@@ -422,9 +442,72 @@ public:
return *this;
}
+#if LLVM_USE_RVALUE_REFERENCES
+ const SmallBitVector &operator=(SmallBitVector &&RHS) {
+ if (this != &RHS) {
+ clear();
+ swap(RHS);
+ }
+ return *this;
+ }
+#endif
+
void swap(SmallBitVector &RHS) {
std::swap(X, RHS.X);
}
+
+ /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
+ /// This computes "*this |= Mask".
+ void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ if (isSmall())
+ applyMask<true, false>(Mask, MaskWords);
+ else
+ getPointer()->setBitsInMask(Mask, MaskWords);
+ }
+
+ /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
+ /// Don't resize. This computes "*this &= ~Mask".
+ void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ if (isSmall())
+ applyMask<false, false>(Mask, MaskWords);
+ else
+ getPointer()->clearBitsInMask(Mask, MaskWords);
+ }
+
+ /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
+ /// Don't resize. This computes "*this |= ~Mask".
+ void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ if (isSmall())
+ applyMask<true, true>(Mask, MaskWords);
+ else
+ getPointer()->setBitsNotInMask(Mask, MaskWords);
+ }
+
+ /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
+ /// Don't resize. This computes "*this &= Mask".
+ void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ if (isSmall())
+ applyMask<false, true>(Mask, MaskWords);
+ else
+ getPointer()->clearBitsNotInMask(Mask, MaskWords);
+ }
+
+private:
+ template<bool AddBits, bool InvertMask>
+ void applyMask(const uint32_t *Mask, unsigned MaskWords) {
+ assert((NumBaseBits == 64 || NumBaseBits == 32) && "Unsupported word size");
+ if (NumBaseBits == 64 && MaskWords >= 2) {
+ uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
+ if (InvertMask) M = ~M;
+ if (AddBits) setSmallBits(getSmallBits() | M);
+ else setSmallBits(getSmallBits() & ~M);
+ } else {
+ uint32_t M = Mask[0];
+ if (InvertMask) M = ~M;
+ if (AddBits) setSmallBits(getSmallBits() | M);
+ else setSmallBits(getSmallBits() & ~M);
+ }
+ }
};
inline SmallBitVector
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index 199783ba3899..c6f0a5bf1542 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -45,7 +45,7 @@ public:
/// @{
/// Assign from a repeated element
- void assign(unsigned NumElts, char Elt) {
+ void assign(size_t NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
@@ -77,6 +77,11 @@ public:
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
}
+
+ void append(size_t NumInputs, char Elt) {
+ SmallVectorImpl<char>::append(NumInputs, Elt);
+ }
+
/// Append from a StringRef
void append(StringRef RHS) {
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 0d9d0d12e868..9fbbbe4f3b5d 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
@@ -54,6 +55,11 @@ protected:
return BeginX == static_cast<const void*>(&FirstEl);
}
+ /// resetToSmall - Put this vector in a state of being small.
+ void resetToSmall() {
+ BeginX = EndX = CapacityX = &FirstEl;
+ }
+
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(size_t MinSizeInBytes, size_t TSize);
@@ -160,28 +166,84 @@ protected:
}
}
- /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
- /// starting with "Dest", constructing elements into it as needed.
+ /// move - Use move-assignment to move the range [I, E) onto the
+ /// objects starting with "Dest". This is just <memory>'s
+ /// std::move, but not all stdlibs actually provide that.
+ template<typename It1, typename It2>
+ static It2 move(It1 I, It1 E, It2 Dest) {
+#if LLVM_USE_RVALUE_REFERENCES
+ for (; I != E; ++I, ++Dest)
+ *Dest = ::std::move(*I);
+ return Dest;
+#else
+ return ::std::copy(I, E, Dest);
+#endif
+ }
+
+ /// move_backward - Use move-assignment to move the range
+ /// [I, E) onto the objects ending at "Dest", moving objects
+ /// in reverse order. This is just <algorithm>'s
+ /// std::move_backward, but not all stdlibs actually provide that.
+ template<typename It1, typename It2>
+ static It2 move_backward(It1 I, It1 E, It2 Dest) {
+#if LLVM_USE_RVALUE_REFERENCES
+ while (I != E)
+ *--Dest = ::std::move(*--E);
+ return Dest;
+#else
+ return ::std::copy_backward(I, E, Dest);
+#endif
+ }
+
+ /// uninitialized_move - Move the range [I, E) into the uninitialized
+ /// memory starting with "Dest", constructing elements as needed.
+ template<typename It1, typename It2>
+ static void uninitialized_move(It1 I, It1 E, It2 Dest) {
+#if LLVM_USE_RVALUE_REFERENCES
+ for (; I != E; ++I, ++Dest)
+ ::new ((void*) &*Dest) T(::std::move(*I));
+#else
+ ::std::uninitialized_copy(I, E, Dest);
+#endif
+ }
+
+ /// uninitialized_copy - Copy the range [I, E) onto the uninitialized
+ /// memory starting with "Dest", constructing elements as needed.
template<typename It1, typename It2>
static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
std::uninitialized_copy(I, E, Dest);
}
- /// grow - double the size of the allocated memory, guaranteeing space for at
- /// least one more element or MinSize if specified.
+ /// grow - Grow the allocated memory (without initializing new
+ /// elements), doubling the size of the allocated memory.
+ /// Guarantees space for at least one more element, or MinSize more
+ /// elements if specified.
void grow(size_t MinSize = 0);
public:
void push_back(const T &Elt) {
if (this->EndX < this->CapacityX) {
Retry:
- new (this->end()) T(Elt);
+ ::new ((void*) this->end()) T(Elt);
this->setEnd(this->end()+1);
return;
}
this->grow();
goto Retry;
}
+
+#if LLVM_USE_RVALUE_REFERENCES
+ void push_back(T &&Elt) {
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ ::new ((void*) this->end()) T(::std::move(Elt));
+ this->setEnd(this->end()+1);
+ return;
+ }
+ this->grow();
+ goto Retry;
+ }
+#endif
void pop_back() {
this->setEnd(this->end()-1);
@@ -199,8 +261,8 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
NewCapacity = MinSize;
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
- // Copy the elements over.
- this->uninitialized_copy(this->begin(), this->end(), NewElts);
+ // Move the elements over.
+ this->uninitialized_move(this->begin(), this->end(), NewElts);
// Destroy the original elements.
destroy_range(this->begin(), this->end());
@@ -225,6 +287,29 @@ protected:
// No need to do a destroy loop for POD's.
static void destroy_range(T *, T *) {}
+ /// move - Use move-assignment to move the range [I, E) onto the
+ /// objects starting with "Dest". For PODs, this is just memcpy.
+ template<typename It1, typename It2>
+ static It2 move(It1 I, It1 E, It2 Dest) {
+ return ::std::copy(I, E, Dest);
+ }
+
+ /// move_backward - Use move-assignment to move the range
+ /// [I, E) onto the objects ending at "Dest", moving objects
+ /// in reverse order.
+ template<typename It1, typename It2>
+ static It2 move_backward(It1 I, It1 E, It2 Dest) {
+ return ::std::copy_backward(I, E, Dest);
+ }
+
+ /// uninitialized_move - Move the range [I, E) onto the uninitialized memory
+ /// starting with "Dest", constructing elements into it as needed.
+ template<typename It1, typename It2>
+ static void uninitialized_move(It1 I, It1 E, It2 Dest) {
+ // Just do a copy.
+ uninitialized_copy(I, E, Dest);
+ }
+
/// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
/// starting with "Dest", constructing elements into it as needed.
template<typename It1, typename It2>
@@ -252,7 +337,7 @@ public:
void push_back(const T &Elt) {
if (this->EndX < this->CapacityX) {
Retry:
- *this->end() = Elt;
+ memcpy(this->end(), &Elt, sizeof(T));
this->setEnd(this->end()+1);
return;
}
@@ -330,7 +415,11 @@ public:
}
T pop_back_val() {
+#if LLVM_USE_RVALUE_REFERENCES
+ T Result = ::std::move(this->back());
+#else
T Result = this->back();
+#endif
this->pop_back();
return Result;
}
@@ -374,36 +463,79 @@ public:
}
iterator erase(iterator I) {
+ assert(I >= this->begin() && "Iterator to erase is out of bounds.");
+ assert(I < this->end() && "Erasing at past-the-end iterator.");
+
iterator N = I;
// Shift all elts down one.
- std::copy(I+1, this->end(), I);
+ this->move(I+1, this->end(), I);
// Drop the last elt.
this->pop_back();
return(N);
}
iterator erase(iterator S, iterator E) {
+ assert(S >= this->begin() && "Range to erase is out of bounds.");
+ assert(S <= E && "Trying to erase invalid range.");
+ assert(E <= this->end() && "Trying to erase past the end.");
+
iterator N = S;
// Shift all elts down.
- iterator I = std::copy(E, this->end(), S);
+ iterator I = this->move(E, this->end(), S);
// Drop the last elts.
this->destroy_range(I, this->end());
this->setEnd(I);
return(N);
}
+#if LLVM_USE_RVALUE_REFERENCES
+ iterator insert(iterator I, T &&Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ this->push_back(::std::move(Elt));
+ return this->end()-1;
+ }
+
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ ::new ((void*) this->end()) T(::std::move(this->back()));
+ this->setEnd(this->end()+1);
+ // Push everything else over.
+ this->move_backward(I, this->end()-1, this->end());
+
+ // If we just moved the element we're inserting, be sure to update
+ // the reference.
+ T *EltPtr = &Elt;
+ if (I <= EltPtr && EltPtr < this->EndX)
+ ++EltPtr;
+
+ *I = ::std::move(*EltPtr);
+ return I;
+ }
+ size_t EltNo = I-this->begin();
+ this->grow();
+ I = this->begin()+EltNo;
+ goto Retry;
+ }
+#endif
+
iterator insert(iterator I, const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
this->push_back(Elt);
return this->end()-1;
}
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+
if (this->EndX < this->CapacityX) {
Retry:
- new (this->end()) T(this->back());
+ ::new ((void*) this->end()) T(this->back());
this->setEnd(this->end()+1);
// Push everything else over.
- std::copy_backward(I, this->end()-1, this->end());
+ this->move_backward(I, this->end()-1, this->end());
// If we just moved the element we're inserting, be sure to update
// the reference.
@@ -421,13 +553,16 @@ public:
}
iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
if (I == this->end()) { // Important special case for empty vector.
append(NumToInsert, Elt);
- return this->end()-1;
+ return this->begin()+InsertElt;
}
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
// Ensure there is enough space.
reserve(static_cast<unsigned>(this->size() + NumToInsert));
@@ -444,7 +579,7 @@ public:
append(this->end()-NumToInsert, this->end());
// Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+ this->move_backward(I, OldEnd-NumToInsert, OldEnd);
std::fill_n(I, NumToInsert, Elt);
return I;
@@ -453,11 +588,11 @@ public:
// Otherwise, we're inserting more elements than exist already, and we're
// not inserting at the end.
- // Copy over the elements that we're about to overwrite.
+ // Move over the elements that we're about to overwrite.
T *OldEnd = this->end();
this->setEnd(this->end() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+ this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
// Replace the overwritten part.
std::fill_n(I, NumOverwritten, Elt);
@@ -469,14 +604,18 @@ public:
template<typename ItTy>
iterator insert(iterator I, ItTy From, ItTy To) {
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
if (I == this->end()) { // Important special case for empty vector.
append(From, To);
- return this->end()-1;
+ return this->begin()+InsertElt;
}
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+
size_t NumToInsert = std::distance(From, To);
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
// Ensure there is enough space.
reserve(static_cast<unsigned>(this->size() + NumToInsert));
@@ -493,7 +632,7 @@ public:
append(this->end()-NumToInsert, this->end());
// Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+ this->move_backward(I, OldEnd-NumToInsert, OldEnd);
std::copy(From, To, I);
return I;
@@ -502,16 +641,16 @@ public:
// Otherwise, we're inserting more elements than exist already, and we're
// not inserting at the end.
- // Copy over the elements that we're about to overwrite.
+ // Move over the elements that we're about to overwrite.
T *OldEnd = this->end();
this->setEnd(this->end() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+ this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
// Replace the overwritten part.
- for (; NumOverwritten > 0; --NumOverwritten) {
- *I = *From;
- ++I; ++From;
+ for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
+ *J = *From;
+ ++J; ++From;
}
// Insert the non-overwritten middle part.
@@ -519,8 +658,11 @@ public:
return I;
}
- const SmallVectorImpl
- &operator=(const SmallVectorImpl &RHS);
+ SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
+#endif
bool operator==(const SmallVectorImpl &RHS) const {
if (this->size() != RHS.size()) return false;
@@ -590,7 +732,7 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
}
template <typename T>
-const SmallVectorImpl<T> &SmallVectorImpl<T>::
+SmallVectorImpl<T> &SmallVectorImpl<T>::
operator=(const SmallVectorImpl<T> &RHS) {
// Avoid self-assignment.
if (this == &RHS) return *this;
@@ -617,6 +759,7 @@ const SmallVectorImpl<T> &SmallVectorImpl<T>::
// If we have to grow to have enough elements, destroy the current elements.
// This allows us to avoid copying them during the grow.
+ // FIXME: don't do this if they're efficiently moveable.
if (this->capacity() < RHSSize) {
// Destroy current elements.
this->destroy_range(this->begin(), this->end());
@@ -637,6 +780,69 @@ const SmallVectorImpl<T> &SmallVectorImpl<T>::
return *this;
}
+#if LLVM_USE_RVALUE_REFERENCES
+template <typename T>
+SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
+ // Avoid self-assignment.
+ if (this == &RHS) return *this;
+
+ // If the RHS isn't small, clear this vector and then steal its buffer.
+ if (!RHS.isSmall()) {
+ this->destroy_range(this->begin(), this->end());
+ if (!this->isSmall()) free(this->begin());
+ this->BeginX = RHS.BeginX;
+ this->EndX = RHS.EndX;
+ this->CapacityX = RHS.CapacityX;
+ RHS.resetToSmall();
+ return *this;
+ }
+
+ // If we already have sufficient space, assign the common elements, then
+ // destroy any excess.
+ size_t RHSSize = RHS.size();
+ size_t CurSize = this->size();
+ if (CurSize >= RHSSize) {
+ // Assign common elements.
+ iterator NewEnd = this->begin();
+ if (RHSSize)
+ NewEnd = this->move(RHS.begin(), RHS.end(), NewEnd);
+
+ // Destroy excess elements and trim the bounds.
+ this->destroy_range(NewEnd, this->end());
+ this->setEnd(NewEnd);
+
+ // Clear the RHS.
+ RHS.clear();
+
+ return *this;
+ }
+
+ // If we have to grow to have enough elements, destroy the current elements.
+ // This allows us to avoid copying them during the grow.
+ // FIXME: this may not actually make any sense if we can efficiently move
+ // elements.
+ if (this->capacity() < RHSSize) {
+ // Destroy current elements.
+ this->destroy_range(this->begin(), this->end());
+ this->setEnd(this->begin());
+ CurSize = 0;
+ this->grow(RHSSize);
+ } else if (CurSize) {
+ // Otherwise, use assignment for the already-constructed elements.
+ this->move(RHS.begin(), RHS.end(), this->begin());
+ }
+
+ // Move-construct the new elements in place.
+ this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
+ this->begin()+CurSize);
+
+ // Set end.
+ this->setEnd(this->begin()+RHSSize);
+
+ RHS.clear();
+ return *this;
+}
+#endif
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements
@@ -692,6 +898,18 @@ public:
return *this;
}
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(NumTsAvailable) {
+ if (!RHS.empty())
+ SmallVectorImpl<T>::operator=(::std::move(RHS));
+ }
+
+ const SmallVector &operator=(SmallVector &&RHS) {
+ SmallVectorImpl<T>::operator=(::std::move(RHS));
+ return *this;
+ }
+#endif
+
};
/// Specialize SmallVector at N=0. This specialization guarantees
@@ -700,7 +918,8 @@ public:
template <typename T>
class SmallVector<T,0> : public SmallVectorImpl<T> {
public:
- SmallVector() : SmallVectorImpl<T>(0) {}
+ SmallVector() : SmallVectorImpl<T>(0) {
+ }
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(0) {
@@ -713,13 +932,26 @@ public:
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
+ if (!RHS.empty())
+ SmallVectorImpl<T>::operator=(RHS);
+ }
+
+ const SmallVector &operator=(const SmallVector &RHS) {
SmallVectorImpl<T>::operator=(RHS);
+ return *this;
}
- SmallVector &operator=(const SmallVectorImpl<T> &RHS) {
- return SmallVectorImpl<T>::operator=(RHS);
+#if LLVM_USE_RVALUE_REFERENCES
+ SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(0) {
+ if (!RHS.empty())
+ SmallVectorImpl<T>::operator=(::std::move(RHS));
}
+ const SmallVector &operator=(SmallVector &&RHS) {
+ SmallVectorImpl<T>::operator=(::std::move(RHS));
+ return *this;
+ }
+#endif
};
template<typename T, unsigned N>
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 923c6a5954d0..556963334894 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -21,33 +21,62 @@
#define LLVM_ADT_SPARSESET_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DataTypes.h"
#include <limits>
namespace llvm {
-/// SparseSetFunctor - Objects in a SparseSet are identified by small integer
-/// keys. A functor object is used to compute the key of an object. The
-/// functor's operator() must return an unsigned smaller than the universe.
+/// 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
+/// 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
+/// directly compares ValueT, only their indices, so it can map keys to
+/// arbitrary values. SparseSetValTraits computes the index from the value
+/// object. To compute the index from a key, SparseSet uses a separate
+/// KeyFunctorT template argument.
///
-/// The default functor implementation forwards to a getSparseSetKey() method
-/// on the object. It is intended for sparse sets holding ad-hoc structs.
+/// A simple type declaration, SparseSet<Type>, handles these cases:
+/// - unsigned key, identity index, identity value
+/// - unsigned key, identity index, fat value providing getSparseSetIndex()
+///
+/// The type declaration SparseSet<Type, UnaryFunction> handles:
+/// - unsigned key, remapped index, identity value (virtual registers)
+/// - pointer key, pointer-derived index, identity value (node+ID)
+/// - pointer key, pointer-derived index, fat value with getSparseSetIndex()
+///
+/// Only other, unexpected cases require specializing SparseSetValTraits.
+///
+/// For best results, ValueT should not require a destructor.
///
template<typename ValueT>
-struct SparseSetFunctor {
- unsigned operator()(const ValueT &Val) {
- return Val.getSparseSetKey();
+struct SparseSetValTraits {
+ static unsigned getValIndex(const ValueT &Val) {
+ return Val.getSparseSetIndex();
}
};
-/// SparseSetFunctor<unsigned> - Provide a trivial identity functor for
-/// SparseSet<unsigned>.
+/// SparseSetValFunctor - Helper class for selecting SparseSetValTraits. The
+/// generic implementation handles ValueT classes which either provide
+/// getSparseSetIndex() or specialize SparseSetValTraits<>.
///
-template<> struct SparseSetFunctor<unsigned> {
- unsigned operator()(unsigned Val) { return Val; }
+template<typename KeyT, typename ValueT, typename KeyFunctorT>
+struct SparseSetValFunctor {
+ unsigned operator()(const ValueT &Val) const {
+ return SparseSetValTraits<ValueT>::getValIndex(Val);
+ }
};
-/// SparseSet - Fast set implementation for objects that can be identified by
+/// SparseSetValFunctor<KeyT, KeyT> - Helper class for the common case of
+/// identity key/value sets.
+template<typename KeyT, typename KeyFunctorT>
+struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
+ unsigned operator()(const KeyT &Key) const {
+ return KeyFunctorT()(Key);
+ }
+};
+
+/// SparseSet - Fast set implmentation for objects that can be identified by
/// small unsigned keys.
///
/// SparseSet allocates memory proportional to the size of the key universe, so
@@ -82,18 +111,20 @@ template<> struct SparseSetFunctor<unsigned> {
/// uint16_t or uint32_t.
///
/// @param ValueT The type of objects in the set.
+/// @param KeyFunctorT A functor that computes an unsigned index from KeyT.
/// @param SparseT An unsigned integer type. See above.
-/// @param KeyFunctorT A functor that computes the unsigned key of a ValueT.
///
template<typename ValueT,
- typename SparseT = uint8_t,
- typename KeyFunctorT = SparseSetFunctor<ValueT> >
+ typename KeyFunctorT = llvm::identity<unsigned>,
+ typename SparseT = uint8_t>
class SparseSet {
+ typedef typename KeyFunctorT::argument_type KeyT;
typedef SmallVector<ValueT, 8> DenseT;
DenseT Dense;
SparseT *Sparse;
unsigned Universe;
- KeyFunctorT KeyOf;
+ KeyFunctorT KeyIndexOf;
+ SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
// Disable copy construction and assignment.
// This data structure is not meant to be used that way.
@@ -160,21 +191,21 @@ public:
Dense.clear();
}
- /// find - Find an element by its key.
+ /// findIndex - Find an element by its index.
///
- /// @param Key A valid key to find.
+ /// @param Idx A valid index to find.
/// @returns An iterator to the element identified by key, or end().
///
- iterator find(unsigned Key) {
- assert(Key < Universe && "Key out of range");
+ iterator findIndex(unsigned Idx) {
+ assert(Idx < Universe && "Key out of range");
assert(std::numeric_limits<SparseT>::is_integer &&
!std::numeric_limits<SparseT>::is_signed &&
"SparseT must be an unsigned integer type");
const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
- for (unsigned i = Sparse[Key], e = size(); i < e; i += Stride) {
- const unsigned FoundKey = KeyOf(Dense[i]);
- assert(FoundKey < Universe && "Invalid key in set. Did object mutate?");
- if (Key == FoundKey)
+ for (unsigned i = Sparse[Idx], e = size(); i < e; i += Stride) {
+ const unsigned FoundIdx = ValIndexOf(Dense[i]);
+ assert(FoundIdx < Universe && "Invalid key in set. Did object mutate?");
+ if (Idx == FoundIdx)
return begin() + i;
// Stride is 0 when SparseT >= unsigned. We don't need to loop.
if (!Stride)
@@ -183,13 +214,22 @@ public:
return end();
}
- const_iterator find(unsigned Key) const {
- return const_cast<SparseSet*>(this)->find(Key);
+ /// find - Find an element by its key.
+ ///
+ /// @param Key A valid key to find.
+ /// @returns An iterator to the element identified by key, or end().
+ ///
+ iterator find(const KeyT &Key) {
+ return findIndex(KeyIndexOf(Key));
+ }
+
+ const_iterator find(const KeyT &Key) const {
+ return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
}
/// count - Returns true if this set contains an element identified by Key.
///
- bool count(unsigned Key) const {
+ bool count(const KeyT &Key) const {
return find(Key) != end();
}
@@ -204,11 +244,11 @@ public:
/// Insertion invalidates all iterators.
///
std::pair<iterator, bool> insert(const ValueT &Val) {
- unsigned Key = KeyOf(Val);
- iterator I = find(Key);
+ unsigned Idx = ValIndexOf(Val);
+ iterator I = findIndex(Idx);
if (I != end())
return std::make_pair(I, false);
- Sparse[Key] = size();
+ Sparse[Idx] = size();
Dense.push_back(Val);
return std::make_pair(end() - 1, true);
}
@@ -216,7 +256,7 @@ public:
/// array subscript - If an element already exists with this key, return it.
/// Otherwise, automatically construct a new value from Key, insert it,
/// and return the newly inserted element.
- ValueT &operator[](unsigned Key) {
+ ValueT &operator[](const KeyT &Key) {
return *insert(ValueT(Key)).first;
}
@@ -238,9 +278,9 @@ public:
assert(unsigned(I - begin()) < size() && "Invalid iterator");
if (I != end() - 1) {
*I = Dense.back();
- unsigned BackKey = KeyOf(Dense.back());
- assert(BackKey < Universe && "Invalid key in set. Did object mutate?");
- Sparse[BackKey] = I - begin();
+ unsigned BackIdx = ValIndexOf(Dense.back());
+ assert(BackIdx < Universe && "Invalid key in set. Did object mutate?");
+ Sparse[BackIdx] = I - begin();
}
// This depends on SmallVector::pop_back() not invalidating iterators.
// std::vector::pop_back() doesn't give that guarantee.
@@ -253,7 +293,7 @@ public:
/// @param Key The key identifying the element to erase.
/// @returns True when an element was erased, false if no element was found.
///
- bool erase(unsigned Key) {
+ bool erase(const KeyT &Key) {
iterator I = find(Key);
if (I == end())
return false;
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 76ba66e746ce..cd846031c5a0 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -12,6 +12,7 @@
#include "llvm/Support/type_traits.h"
+#include <algorithm>
#include <cassert>
#include <cstring>
#include <limits>
@@ -292,6 +293,16 @@ namespace llvm {
/// Note: O(size() + Chars.size())
size_type find_last_of(StringRef Chars, size_t From = npos) const;
+ /// find_last_not_of - Find the last character in the string that is not
+ /// \arg C, or npos if not found.
+ size_type find_last_not_of(char C, size_t From = npos) const;
+
+ /// find_last_not_of - Find the last character in the string that is not in
+ /// \arg Chars, or npos if not found.
+ ///
+ /// Note: O(size() + Chars.size())
+ size_type find_last_not_of(StringRef Chars, size_t From = npos) const;
+
/// @}
/// @name Helpful Algorithms
/// @{
@@ -480,6 +491,24 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
+ /// ltrim - Return string with consecutive characters in \arg Chars starting
+ /// from the left removed.
+ StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
+ return drop_front(std::min(Length, find_first_not_of(Chars)));
+ }
+
+ /// rtrim - Return string with consecutive characters in \arg Chars starting
+ /// from the right removed.
+ StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
+ return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
+ }
+
+ /// trim - Return string with consecutive characters in \arg Chars starting
+ /// from the left and right removed.
+ StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
+ return ltrim(Chars).rtrim(Chars);
+ }
+
/// @}
};
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h
index 74805830d854..7fd6e2796032 100644
--- a/include/llvm/ADT/StringSwitch.h
+++ b/include/llvm/ADT/StringSwitch.h
@@ -48,8 +48,8 @@ class StringSwitch {
const T *Result;
public:
- explicit StringSwitch(StringRef Str)
- : Str(Str), Result(0) { }
+ explicit StringSwitch(StringRef S)
+ : Str(S), Result(0) { }
template<unsigned N>
StringSwitch& Case(const char (&S)[N], const T& Value) {
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index 5014517c9e05..d3d33b8adde1 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -10,8 +10,11 @@
#ifndef LLVM_ADT_TINYPTRVECTOR_H
#define LLVM_ADT_TINYPTRVECTOR_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -25,18 +28,78 @@ template <typename EltTy>
class TinyPtrVector {
public:
typedef llvm::SmallVector<EltTy, 4> VecTy;
+ typedef typename VecTy::value_type value_type;
+
llvm::PointerUnion<EltTy, VecTy*> Val;
-
+
TinyPtrVector() {}
+ ~TinyPtrVector() {
+ if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ delete V;
+ }
+
TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
if (VecTy *V = Val.template dyn_cast<VecTy*>())
Val = new VecTy(*V);
}
- ~TinyPtrVector() {
- if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ TinyPtrVector &operator=(const TinyPtrVector &RHS) {
+ if (this == &RHS)
+ return *this;
+ if (RHS.empty()) {
+ this->clear();
+ return *this;
+ }
+
+ // Try to squeeze into the single slot. If it won't fit, allocate a copied
+ // vector.
+ if (Val.template is<EltTy>()) {
+ if (RHS.size() == 1)
+ Val = RHS.front();
+ else
+ Val = new VecTy(*RHS.Val.template get<VecTy*>());
+ return *this;
+ }
+
+ // If we have a full vector allocated, try to re-use it.
+ if (RHS.Val.template is<EltTy>()) {
+ Val.template get<VecTy*>()->clear();
+ Val.template get<VecTy*>()->push_back(RHS.front());
+ } else {
+ *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>();
+ }
+ return *this;
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
+ RHS.Val = (EltTy)0;
+ }
+ TinyPtrVector &operator=(TinyPtrVector &&RHS) {
+ if (this == &RHS)
+ return *this;
+ if (RHS.empty()) {
+ this->clear();
+ return *this;
+ }
+
+ // If this vector has been allocated on the heap, re-use it if cheap. If it
+ // would require more copying, just delete it and we'll steal the other
+ // side.
+ if (VecTy *V = Val.template dyn_cast<VecTy*>()) {
+ if (RHS.Val.template is<EltTy>()) {
+ V->clear();
+ V->push_back(RHS.front());
+ return *this;
+ }
delete V;
+ }
+
+ Val = RHS.Val;
+ RHS.Val = (EltTy)0;
+ return *this;
}
-
+#endif
+
// implicit conversion operator to ArrayRef.
operator ArrayRef<EltTy>() const {
if (Val.isNull())
@@ -45,7 +108,7 @@ public:
return *Val.getAddrOfPtr1();
return *Val.template get<VecTy*>();
}
-
+
bool empty() const {
// This vector can be empty if it contains no element, or if it
// contains a pointer to an empty vector.
@@ -54,7 +117,7 @@ public:
return Vec->empty();
return false;
}
-
+
unsigned size() const {
if (empty())
return 0;
@@ -62,27 +125,21 @@ public:
return 1;
return Val.template get<VecTy*>()->size();
}
-
+
typedef const EltTy *const_iterator;
typedef EltTy *iterator;
iterator begin() {
- if (empty())
- return 0;
-
if (Val.template is<EltTy>())
return Val.getAddrOfPtr1();
-
+
return Val.template get<VecTy *>()->begin();
}
iterator end() {
- if (empty())
- return 0;
-
if (Val.template is<EltTy>())
- return begin() + 1;
-
+ return begin() + (Val.isNull() ? 0 : 1);
+
return Val.template get<VecTy *>()->end();
}
@@ -100,38 +157,53 @@ public:
assert(i == 0 && "tinyvector index out of range");
return V;
}
-
- assert(i < Val.template get<VecTy*>()->size() &&
+
+ assert(i < Val.template get<VecTy*>()->size() &&
"tinyvector index out of range");
return (*Val.template get<VecTy*>())[i];
}
-
+
EltTy front() const {
assert(!empty() && "vector empty");
if (EltTy V = Val.template dyn_cast<EltTy>())
return V;
return Val.template get<VecTy*>()->front();
}
-
+
+ EltTy back() const {
+ assert(!empty() && "vector empty");
+ if (EltTy V = Val.template dyn_cast<EltTy>())
+ return V;
+ return Val.template get<VecTy*>()->back();
+ }
+
void push_back(EltTy NewVal) {
assert(NewVal != 0 && "Can't add a null value");
-
+
// If we have nothing, add something.
if (Val.isNull()) {
Val = NewVal;
return;
}
-
+
// If we have a single value, convert to a vector.
if (EltTy V = Val.template dyn_cast<EltTy>()) {
Val = new VecTy();
Val.template get<VecTy*>()->push_back(V);
}
-
+
// Add the new value, we know we have a vector.
Val.template get<VecTy*>()->push_back(NewVal);
}
-
+
+ void pop_back() {
+ // If we have a single value, convert to empty.
+ if (Val.template is<EltTy>())
+ Val = (EltTy)0;
+ else if (VecTy *Vec = Val.template get<VecTy*>())
+ Vec->pop_back();
+ }
+
void clear() {
// If we have a single value, convert to empty.
if (Val.template is<EltTy>()) {
@@ -144,6 +216,9 @@ public:
}
iterator erase(iterator I) {
+ assert(I >= begin() && "Iterator to erase is out of bounds.");
+ assert(I < end() && "Erasing at past-the-end iterator.");
+
// If we have a single value, convert to empty.
if (Val.template is<EltTy>()) {
if (I == begin())
@@ -153,12 +228,63 @@ public:
// benefit to collapsing back to a pointer
return Vec->erase(I);
}
+ return end();
+ }
+
+ iterator erase(iterator S, iterator E) {
+ assert(S >= begin() && "Range to erase is out of bounds.");
+ assert(S <= E && "Trying to erase invalid range.");
+ assert(E <= end() && "Trying to erase past the end.");
+
+ if (Val.template is<EltTy>()) {
+ if (S == begin() && S != E)
+ Val = (EltTy)0;
+ } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+ return Vec->erase(S, E);
+ }
+ return end();
+ }
- return 0;
+ iterator insert(iterator I, const EltTy &Elt) {
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+ if (I == end()) {
+ push_back(Elt);
+ return llvm::prior(end());
+ }
+ assert(!Val.isNull() && "Null value with non-end insert iterator.");
+ if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ assert(I == begin());
+ Val = Elt;
+ push_back(V);
+ return begin();
+ }
+
+ return Val.template get<VecTy*>()->insert(I, Elt);
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+ if (From == To)
+ return I;
+
+ // If we have a single value, convert to a vector.
+ ptrdiff_t Offset = I - begin();
+ if (Val.isNull()) {
+ if (llvm::next(From) == To) {
+ Val = *From;
+ return begin();
+ }
+
+ Val = new VecTy();
+ } else if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ Val = new VecTy();
+ Val.template get<VecTy*>()->push_back(V);
+ }
+ return Val.template get<VecTy*>()->insert(begin() + Offset, From, To);
}
-
-private:
- void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
};
} // end namespace llvm
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index f5f99d0f1b82..7f7061ab01b9 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -62,8 +62,8 @@ public:
x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore
mblaze, // MBlaze: mblaze
- ptx32, // PTX: ptx (32-bit)
- ptx64, // PTX: ptx (64-bit)
+ nvptx, // NVPTX: 32-bit
+ nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil // amdil: amd IL
};
@@ -98,7 +98,8 @@ public:
Minix,
RTEMS,
NativeClient,
- CNK // BG/P Compute-Node Kernel
+ CNK, // BG/P Compute-Node Kernel
+ Bitrig
};
enum EnvironmentType {
UnknownEnvironment,
@@ -194,6 +195,11 @@ public:
bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
unsigned &Micro) const;
+ /// getiOSVersion - Parse the version number as with getOSVersion. This should
+ /// only be called with IOS triples.
+ void getiOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const;
+
/// @}
/// @name Direct Component Access
/// @{
@@ -266,7 +272,7 @@ public:
/// compatibility, which handles supporting skewed version numbering schemes
/// used by the "darwin" triples.
unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
- unsigned Micro = 0) const {
+ unsigned Micro = 0) const {
assert(isMacOSX() && "Not an OS X triple!");
// If this is OS X, expect a sane version number.
diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h
index 707d07d32cbc..f7e255181e23 100644
--- a/include/llvm/ADT/ValueMap.h
+++ b/include/llvm/ADT/ValueMap.h
@@ -111,20 +111,21 @@ public:
/// count - Return true if the specified key is in the map.
bool count(const KeyT &Val) const {
- return Map.count(Wrap(Val));
+ return Map.find_as(Val) != Map.end();
}
iterator find(const KeyT &Val) {
- return iterator(Map.find(Wrap(Val)));
+ return iterator(Map.find_as(Val));
}
const_iterator find(const KeyT &Val) const {
- return const_iterator(Map.find(Wrap(Val)));
+ return const_iterator(Map.find_as(Val));
}
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueT lookup(const KeyT &Val) const {
- return Map.lookup(Wrap(Val));
+ typename MapT::const_iterator I = Map.find_as(Val);
+ return I != Map.end() ? I->second : ValueT();
}
// Inserts key,value pair into the map if the key isn't already in the map.
@@ -145,7 +146,12 @@ public:
bool erase(const KeyT &Val) {
- return Map.erase(Wrap(Val));
+ typename MapT::iterator I = Map.find_as(Val);
+ if (I == Map.end())
+ return false;
+
+ Map.erase(I);
+ return true;
}
void erase(iterator I) {
return Map.erase(I.base());
@@ -256,9 +262,15 @@ struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > {
static unsigned getHashValue(const VH &Val) {
return PointerInfo::getHashValue(Val.Unwrap());
}
+ static unsigned getHashValue(const KeyT &Val) {
+ return PointerInfo::getHashValue(Val);
+ }
static bool isEqual(const VH &LHS, const VH &RHS) {
return LHS == RHS;
}
+ static bool isEqual(const KeyT &LHS, const VH &RHS) {
+ return LHS == RHS.getValPtr();
+ }
};
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index b823f71a2217..674868a02633 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -50,6 +50,7 @@ class Pass;
class AnalysisUsage;
class MemTransferInst;
class MemIntrinsic;
+class DominatorTree;
class AliasAnalysis {
protected:
@@ -462,6 +463,18 @@ public:
virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2);
+ /// callCapturesBefore - Return information about whether a particular call
+ /// site modifies or reads the specified memory location.
+ ModRefResult callCapturesBefore(const Instruction *I,
+ const AliasAnalysis::Location &MemLoc,
+ DominatorTree *DT);
+
+ /// callCapturesBefore - A convenience wrapper.
+ ModRefResult callCapturesBefore(const Instruction *I, const Value *P,
+ uint64_t Size, DominatorTree *DT) {
+ return callCapturesBefore(I, Location(P, Size), DT);
+ }
+
//===--------------------------------------------------------------------===//
/// Higher level methods for querying mod/ref information.
///
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
index 6f2ccfb19901..5168ab78729b 100644
--- a/include/llvm/Analysis/BlockFrequencyImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -217,7 +217,7 @@ class BlockFrequencyImpl {
divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
}
- /// doLoop - Propagate block frequency down throught the loop.
+ /// doLoop - Propagate block frequency down through the loop.
void doLoop(BlockT *Head, BlockT *Tail) {
DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
<< getBlockName(Tail) << ")\n");
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 711607834921..03c807cf8326 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -16,6 +16,7 @@
#define LLVM_ANALYSIS_CODEMETRICS_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CallSite.h"
namespace llvm {
class BasicBlock;
@@ -29,10 +30,11 @@ namespace llvm {
/// \brief Check whether a call will lower to something small.
///
- /// This tests checks whether calls to this function will lower to something
+ /// This tests checks whether this callsite will lower to something
/// significantly cheaper than a traditional call, often a single
- /// instruction.
- bool callIsSmall(const Function *F);
+ /// 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 set
/// of basic blocks.
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index 6e8e4246367e..1289eddf51b9 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -152,7 +152,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
template<class NodeT>
-static raw_ostream &operator<<(raw_ostream &o,
+inline raw_ostream &operator<<(raw_ostream &o,
const DomTreeNodeBase<NodeT> *Node) {
if (Node->getBlock())
WriteAsOperand(o, Node->getBlock(), false);
@@ -165,7 +165,7 @@ static raw_ostream &operator<<(raw_ostream &o,
}
template<class NodeT>
-static void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
+inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
unsigned Lev) {
o.indent(2*Lev) << "[" << Lev << "] " << N;
for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
@@ -705,6 +705,8 @@ DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+class BasicBlockEdge;
+
//===-------------------------------------
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
/// compute a normal dominator tree.
@@ -778,6 +780,8 @@ public:
bool dominates(const Instruction *Def, const Use &U) const;
bool dominates(const Instruction *Def, const Instruction *User) const;
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
+ bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
+ bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const {
return DT->properlyDominates(A, B);
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 691c2d19be9a..0cba135222b9 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -127,10 +127,6 @@ namespace llvm {
// adding a replacement API.
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
};
-
- /// callIsSmall - If a call is likely to lower to a single target instruction,
- /// or is otherwise deemed small return true.
- bool callIsSmall(const Function *Callee);
}
#endif
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 91feaaac038d..eeb482d82a2b 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -46,7 +46,7 @@
namespace llvm {
template<typename T>
-static 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);
assert(I != V.end() && "N is not in this list!");
V.erase(I);
@@ -97,6 +97,9 @@ public:
BlockT *getHeader() const { return Blocks.front(); }
LoopT *getParentLoop() const { return ParentLoop; }
+ /// setParentLoop is a raw interface for bypassing addChildLoop.
+ void setParentLoop(LoopT *L) { ParentLoop = L; }
+
/// contains - Return true if the specified loop is contained within in
/// this loop.
///
@@ -122,14 +125,20 @@ public:
/// iterator/begin/end - Return the loops contained entirely within this loop.
///
const std::vector<LoopT *> &getSubLoops() const { return SubLoops; }
+ std::vector<LoopT *> &getSubLoopsVector() { return SubLoops; }
typedef typename std::vector<LoopT *>::const_iterator iterator;
+ typedef typename std::vector<LoopT *>::const_reverse_iterator
+ reverse_iterator;
iterator begin() const { return SubLoops.begin(); }
iterator end() const { return SubLoops.end(); }
+ reverse_iterator rbegin() const { return SubLoops.rbegin(); }
+ reverse_iterator rend() const { return SubLoops.rend(); }
bool empty() const { return SubLoops.empty(); }
/// getBlocks - Get a list of the basic blocks which make up this loop.
///
const std::vector<BlockT*> &getBlocks() const { return Blocks; }
+ std::vector<BlockT*> &getBlocksVector() { return Blocks; }
typedef typename std::vector<BlockT*>::const_iterator block_iterator;
block_iterator block_begin() const { return Blocks.begin(); }
block_iterator block_end() const { return Blocks.end(); }
@@ -181,83 +190,26 @@ public:
/// outside of the loop. These are the blocks _inside of the current loop_
/// which branch out. The returned list is always unique.
///
- void getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
- // Sort the blocks vector so that we can use binary search to do quick
- // lookups.
- SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
- std::sort(LoopBBs.begin(), LoopBBs.end());
-
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) {
- // Not in current loop? It must be an exit block.
- ExitingBlocks.push_back(*BI);
- break;
- }
- }
+ void getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const;
/// getExitingBlock - If getExitingBlocks would return exactly one block,
/// return that block. Otherwise return null.
- BlockT *getExitingBlock() const {
- SmallVector<BlockT*, 8> ExitingBlocks;
- getExitingBlocks(ExitingBlocks);
- if (ExitingBlocks.size() == 1)
- return ExitingBlocks[0];
- return 0;
- }
+ BlockT *getExitingBlock() const;
/// getExitBlocks - Return all of the successor blocks of this loop. These
/// are the blocks _outside of the current loop_ which are branched to.
///
- void getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
- // Sort the blocks vector so that we can use binary search to do quick
- // lookups.
- SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
- std::sort(LoopBBs.begin(), LoopBBs.end());
-
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
- // Not in current loop? It must be an exit block.
- ExitBlocks.push_back(*I);
- }
+ void getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const;
/// getExitBlock - If getExitBlocks would return exactly one block,
/// return that block. Otherwise return null.
- BlockT *getExitBlock() const {
- SmallVector<BlockT*, 8> ExitBlocks;
- getExitBlocks(ExitBlocks);
- if (ExitBlocks.size() == 1)
- return ExitBlocks[0];
- return 0;
- }
+ BlockT *getExitBlock() const;
/// Edge type.
- typedef std::pair<BlockT*, BlockT*> Edge;
+ typedef std::pair<const BlockT*, const BlockT*> Edge;
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
- template <typename EdgeT>
- void getExitEdges(SmallVectorImpl<EdgeT> &ExitEdges) const {
- // Sort the blocks vector so that we can use binary search to do quick
- // lookups.
- SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
- array_pod_sort(LoopBBs.begin(), LoopBBs.end());
-
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
- // Not in current loop? It must be an exit block.
- ExitEdges.push_back(EdgeT(*BI, *I));
- }
+ void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const;
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
@@ -266,71 +218,18 @@ public:
///
/// This method returns null if there is no preheader for the loop.
///
- BlockT *getLoopPreheader() const {
- // Keep track of nodes outside the loop branching to the header...
- BlockT *Out = getLoopPredecessor();
- if (!Out) return 0;
-
- // Make sure there is only one exit out of the preheader.
- typedef GraphTraits<BlockT*> BlockTraits;
- typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
- ++SI;
- if (SI != BlockTraits::child_end(Out))
- return 0; // Multiple exits from the block, must not be a preheader.
-
- // The predecessor has exactly one successor, so it is a preheader.
- return Out;
- }
+ BlockT *getLoopPreheader() const;
/// getLoopPredecessor - If the given loop's header has exactly one unique
/// predecessor outside the loop, return it. Otherwise return null.
/// This is less strict that the loop "preheader" concept, which requires
/// the predecessor to have exactly one successor.
///
- BlockT *getLoopPredecessor() const {
- // Keep track of nodes outside the loop branching to the header...
- BlockT *Out = 0;
-
- // Loop over the predecessors of the header node...
- BlockT *Header = getHeader();
- typedef GraphTraits<BlockT*> BlockTraits;
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(Header),
- PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
- typename InvBlockTraits::NodeType *N = *PI;
- if (!contains(N)) { // If the block is not in the loop...
- if (Out && Out != N)
- return 0; // Multiple predecessors outside the loop
- Out = N;
- }
- }
-
- // Make sure there is only one exit out of the preheader.
- assert(Out && "Header of loop has no predecessors from outside loop?");
- return Out;
- }
+ BlockT *getLoopPredecessor() const;
/// getLoopLatch - If there is a single latch block for this loop, return it.
/// A latch block is a block that contains a branch back to the header.
- BlockT *getLoopLatch() const {
- BlockT *Header = getHeader();
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(Header);
- typename InvBlockTraits::ChildIteratorType PE =
- InvBlockTraits::child_end(Header);
- BlockT *Latch = 0;
- for (; PI != PE; ++PI) {
- typename InvBlockTraits::NodeType *N = *PI;
- if (contains(N)) {
- if (Latch) return 0;
- Latch = N;
- }
- }
-
- return Latch;
- }
+ BlockT *getLoopLatch() const;
//===--------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
@@ -348,17 +247,7 @@ public:
/// the OldChild entry in our children list with NewChild, and updates the
/// parent pointer of OldChild to be null and the NewChild to be this loop.
/// This updates the loop depth of the new child.
- void replaceChildLoopWith(LoopT *OldChild,
- LoopT *NewChild) {
- assert(OldChild->ParentLoop == this && "This loop is already broken!");
- assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
- typename std::vector<LoopT *>::iterator I =
- std::find(SubLoops.begin(), SubLoops.end(), OldChild);
- assert(I != SubLoops.end() && "OldChild not in loop!");
- *I = NewChild;
- OldChild->ParentLoop = 0;
- NewChild->ParentLoop = static_cast<LoopT *>(this);
- }
+ void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild);
/// addChildLoop - Add the specified loop to be a child of this loop. This
/// updates the loop depth of the new child.
@@ -411,121 +300,12 @@ public:
}
/// verifyLoop - Verify loop structure
- void verifyLoop() const {
-#ifndef NDEBUG
- assert(!Blocks.empty() && "Loop header is missing");
-
- // Setup for using a depth-first iterator to visit every block in the loop.
- SmallVector<BlockT*, 8> ExitBBs;
- getExitBlocks(ExitBBs);
- llvm::SmallPtrSet<BlockT*, 8> VisitSet;
- VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
- df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
- BI = df_ext_begin(getHeader(), VisitSet),
- BE = df_ext_end(getHeader(), VisitSet);
-
- // Keep track of the number of BBs visited.
- unsigned NumVisited = 0;
-
- // Sort the blocks vector so that we can use binary search to do quick
- // lookups.
- SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
- std::sort(LoopBBs.begin(), LoopBBs.end());
-
- // Check the individual blocks.
- for ( ; BI != BE; ++BI) {
- BlockT *BB = *BI;
- bool HasInsideLoopSuccs = false;
- bool HasInsideLoopPreds = false;
- SmallVector<BlockT *, 2> OutsideLoopPreds;
-
- typedef GraphTraits<BlockT*> BlockTraits;
- for (typename BlockTraits::ChildIteratorType SI =
- BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
- SI != SE; ++SI)
- if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *SI)) {
- HasInsideLoopSuccs = true;
- break;
- }
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
- PI != PE; ++PI) {
- BlockT *N = *PI;
- if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N))
- HasInsideLoopPreds = true;
- else
- OutsideLoopPreds.push_back(N);
- }
-
- if (BB == getHeader()) {
- assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
- } else if (!OutsideLoopPreds.empty()) {
- // A non-header loop shouldn't be reachable from outside the loop,
- // though it is permitted if the predecessor is not itself actually
- // reachable.
- BlockT *EntryBB = BB->getParent()->begin();
- for (df_iterator<BlockT *> NI = df_begin(EntryBB),
- NE = df_end(EntryBB); NI != NE; ++NI)
- for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
- assert(*NI != OutsideLoopPreds[i] &&
- "Loop has multiple entry points!");
- }
- assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!");
- assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
- assert(BB != getHeader()->getParent()->begin() &&
- "Loop contains function entry block!");
-
- NumVisited++;
- }
-
- assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
-
- // Check the subloops.
- for (iterator I = begin(), E = end(); I != E; ++I)
- // Each block in each subloop should be contained within this loop.
- for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
- BI != BE; ++BI) {
- assert(std::binary_search(LoopBBs.begin(), LoopBBs.end(), *BI) &&
- "Loop does not contain all the blocks of a subloop!");
- }
-
- // Check the parent loop pointer.
- if (ParentLoop) {
- assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) !=
- ParentLoop->end() &&
- "Loop is not a subloop of its parent!");
- }
-#endif
- }
+ void verifyLoop() const;
/// verifyLoop - Verify loop structure of this loop and all nested loops.
- void verifyLoopNest(DenseSet<const LoopT*> *Loops) const {
- Loops->insert(static_cast<const LoopT *>(this));
- // Verify this loop.
- verifyLoop();
- // Verify the subloops.
- for (iterator I = begin(), E = end(); I != E; ++I)
- (*I)->verifyLoopNest(Loops);
- }
+ void verifyLoopNest(DenseSet<const LoopT*> *Loops) const;
- void print(raw_ostream &OS, unsigned Depth = 0) const {
- OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
- << " containing: ";
-
- for (unsigned i = 0; i < getBlocks().size(); ++i) {
- if (i) OS << ",";
- BlockT *BB = getBlocks()[i];
- WriteAsOperand(OS, BB, false);
- if (BB == getHeader()) OS << "<header>";
- if (BB == getLoopLatch()) OS << "<latch>";
- if (isLoopExiting(BB)) OS << "<exiting>";
- }
- OS << "\n";
-
- for (iterator I = begin(), E = end(); I != E; ++I)
- (*I)->print(OS, Depth+2);
- }
+ void print(raw_ostream &OS, unsigned Depth = 0) const;
protected:
friend class LoopInfoBase<BlockT, LoopT>;
@@ -540,6 +320,11 @@ raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
return OS;
}
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template class LoopBase<BasicBlock, Loop>;
+#endif
+
class Loop : public LoopBase<BasicBlock, Loop> {
public:
Loop() {}
@@ -650,8 +435,12 @@ public:
/// function.
///
typedef typename std::vector<LoopT *>::const_iterator iterator;
+ typedef typename std::vector<LoopT *>::const_reverse_iterator
+ reverse_iterator;
iterator begin() const { return TopLevelLoops.begin(); }
iterator end() const { return TopLevelLoops.end(); }
+ reverse_iterator rbegin() const { return TopLevelLoops.rbegin(); }
+ reverse_iterator rend() const { return TopLevelLoops.rend(); }
bool empty() const { return TopLevelLoops.empty(); }
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
@@ -744,189 +533,19 @@ public:
return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
}
- void Calculate(DominatorTreeBase<BlockT> &DT) {
- BlockT *RootNode = DT.getRootNode()->getBlock();
-
- for (df_iterator<BlockT*> NI = df_begin(RootNode),
- NE = df_end(RootNode); NI != NE; ++NI)
- if (LoopT *L = ConsiderForLoop(*NI, DT))
- TopLevelLoops.push_back(L);
- }
-
- LoopT *ConsiderForLoop(BlockT *BB, DominatorTreeBase<BlockT> &DT) {
- if (BBMap.count(BB)) return 0; // Haven't processed this node?
-
- std::vector<BlockT *> TodoStack;
-
- // Scan the predecessors of BB, checking to see if BB dominates any of
- // them. This identifies backedges which target this node...
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType I =
- InvBlockTraits::child_begin(BB), E = InvBlockTraits::child_end(BB);
- I != E; ++I) {
- typename InvBlockTraits::NodeType *N = *I;
- // If BB dominates its predecessor...
- if (DT.dominates(BB, N) && DT.isReachableFromEntry(N))
- TodoStack.push_back(N);
- }
-
- if (TodoStack.empty()) return 0; // No backedges to this block...
-
- // Create a new loop to represent this basic block...
- LoopT *L = new LoopT(BB);
- BBMap[BB] = L;
-
- while (!TodoStack.empty()) { // Process all the nodes in the loop
- BlockT *X = TodoStack.back();
- TodoStack.pop_back();
-
- if (!L->contains(X) && // As of yet unprocessed??
- DT.isReachableFromEntry(X)) {
- // Check to see if this block already belongs to a loop. If this occurs
- // then we have a case where a loop that is supposed to be a child of
- // the current loop was processed before the current loop. When this
- // occurs, this child loop gets added to a part of the current loop,
- // making it a sibling to the current loop. We have to reparent this
- // loop.
- if (LoopT *SubLoop =
- const_cast<LoopT *>(getLoopFor(X)))
- if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)){
- // Remove the subloop from its current parent...
- assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L);
- LoopT *SLP = SubLoop->ParentLoop; // SubLoopParent
- typename std::vector<LoopT *>::iterator I =
- std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop);
- assert(I != SLP->SubLoops.end() &&"SubLoop not a child of parent?");
- SLP->SubLoops.erase(I); // Remove from parent...
-
- // Add the subloop to THIS loop...
- SubLoop->ParentLoop = L;
- L->SubLoops.push_back(SubLoop);
- }
-
- // Normal case, add the block to our loop...
- L->Blocks.push_back(X);
-
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
-
- // Add all of the predecessors of X to the end of the work stack...
- TodoStack.insert(TodoStack.end(), InvBlockTraits::child_begin(X),
- InvBlockTraits::child_end(X));
- }
- }
-
- // If there are any loops nested within this loop, create them now!
- for (typename std::vector<BlockT*>::iterator I = L->Blocks.begin(),
- E = L->Blocks.end(); I != E; ++I)
- if (LoopT *NewLoop = ConsiderForLoop(*I, DT)) {
- L->SubLoops.push_back(NewLoop);
- NewLoop->ParentLoop = L;
- }
-
- // Add the basic blocks that comprise this loop to the BBMap so that this
- // loop can be found for them.
- //
- for (typename std::vector<BlockT*>::iterator I = L->Blocks.begin(),
- E = L->Blocks.end(); I != E; ++I)
- BBMap.insert(std::make_pair(*I, L));
-
- // Now that we have a list of all of the child loops of this loop, check to
- // see if any of them should actually be nested inside of each other. We
- // can accidentally pull loops our of their parents, so we must make sure to
- // organize the loop nests correctly now.
- {
- std::map<BlockT *, LoopT *> ContainingLoops;
- for (unsigned i = 0; i != L->SubLoops.size(); ++i) {
- LoopT *Child = L->SubLoops[i];
- assert(Child->getParentLoop() == L && "Not proper child loop?");
-
- if (LoopT *ContainingLoop = ContainingLoops[Child->getHeader()]) {
- // If there is already a loop which contains this loop, move this loop
- // into the containing loop.
- MoveSiblingLoopInto(Child, ContainingLoop);
- --i; // The loop got removed from the SubLoops list.
- } else {
- // This is currently considered to be a top-level loop. Check to see
- // if any of the contained blocks are loop headers for subloops we
- // have already processed.
- for (unsigned b = 0, e = Child->Blocks.size(); b != e; ++b) {
- LoopT *&BlockLoop = ContainingLoops[Child->Blocks[b]];
- if (BlockLoop == 0) { // Child block not processed yet...
- BlockLoop = Child;
- } else if (BlockLoop != Child) {
- LoopT *SubLoop = BlockLoop;
- // Reparent all of the blocks which used to belong to BlockLoops
- for (unsigned j = 0, f = SubLoop->Blocks.size(); j != f; ++j)
- ContainingLoops[SubLoop->Blocks[j]] = Child;
-
- // There is already a loop which contains this block, that means
- // that we should reparent the loop which the block is currently
- // considered to belong to to be a child of this loop.
- MoveSiblingLoopInto(SubLoop, Child);
- --i; // We just shrunk the SubLoops list.
- }
- }
- }
- }
- }
-
- return L;
- }
-
- /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside
- /// of the NewParent Loop, instead of being a sibling of it.
- void MoveSiblingLoopInto(LoopT *NewChild,
- LoopT *NewParent) {
- LoopT *OldParent = NewChild->getParentLoop();
- assert(OldParent && OldParent == NewParent->getParentLoop() &&
- NewChild != NewParent && "Not sibling loops!");
-
- // Remove NewChild from being a child of OldParent
- typename std::vector<LoopT *>::iterator I =
- std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(),
- NewChild);
- assert(I != OldParent->SubLoops.end() && "Parent fields incorrect??");
- OldParent->SubLoops.erase(I); // Remove from parent's subloops list
- NewChild->ParentLoop = 0;
-
- InsertLoopInto(NewChild, NewParent);
- }
-
- /// InsertLoopInto - This inserts loop L into the specified parent loop. If
- /// the parent loop contains a loop which should contain L, the loop gets
- /// inserted into L instead.
- void InsertLoopInto(LoopT *L, LoopT *Parent) {
- BlockT *LHeader = L->getHeader();
- assert(Parent->contains(LHeader) &&
- "This loop should not be inserted here!");
-
- // Check to see if it belongs in a child loop...
- for (unsigned i = 0, e = static_cast<unsigned>(Parent->SubLoops.size());
- i != e; ++i)
- if (Parent->SubLoops[i]->contains(LHeader)) {
- InsertLoopInto(L, Parent->SubLoops[i]);
- return;
- }
-
- // If not, insert it here!
- Parent->SubLoops.push_back(L);
- L->ParentLoop = Parent;
- }
+ /// Create the loop forest using a stable algorithm.
+ void Analyze(DominatorTreeBase<BlockT> &DomTree);
// Debugging
- void print(raw_ostream &OS) const {
- for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
- TopLevelLoops[i]->print(OS);
- #if 0
- for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
- E = BBMap.end(); I != E; ++I)
- OS << "BB '" << I->first->getName() << "' level = "
- << I->second->getLoopDepth() << "\n";
- #endif
- }
+ void print(raw_ostream &OS) const;
};
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template class LoopInfoBase<BasicBlock, Loop>;
+#endif
+
class LoopInfo : public FunctionPass {
LoopInfoBase<BasicBlock, Loop> LI;
friend class LoopBase<BasicBlock, Loop>;
@@ -946,8 +565,11 @@ public:
/// function.
///
typedef LoopInfoBase<BasicBlock, Loop>::iterator iterator;
+ typedef LoopInfoBase<BasicBlock, Loop>::reverse_iterator reverse_iterator;
inline iterator begin() const { return LI.begin(); }
inline iterator end() const { return LI.end(); }
+ inline reverse_iterator rbegin() const { return LI.rbegin(); }
+ inline reverse_iterator rend() const { return LI.rend(); }
bool empty() const { return LI.empty(); }
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
@@ -1074,27 +696,6 @@ template <> struct GraphTraits<Loop*> {
}
};
-template<class BlockT, class LoopT>
-void
-LoopBase<BlockT, LoopT>::addBasicBlockToLoop(BlockT *NewBB,
- LoopInfoBase<BlockT, LoopT> &LIB) {
- assert((Blocks.empty() || LIB[getHeader()] == this) &&
- "Incorrect LI specified for this loop!");
- assert(NewBB && "Cannot add a null basic block to the loop!");
- assert(LIB[NewBB] == 0 && "BasicBlock already in the loop!");
-
- LoopT *L = static_cast<LoopT *>(this);
-
- // Add the loop mapping to the LoopInfo object...
- LIB.BBMap[NewBB] = L;
-
- // Add the basic block to this loop and all parent loops...
- while (L) {
- L->Blocks.push_back(NewBB);
- L = L->getParentLoop();
- }
-}
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
new file mode 100644
index 000000000000..c07fbf7aa827
--- /dev/null
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -0,0 +1,570 @@
+//===- llvm/Analysis/LoopInfoImpl.h - Natural Loop Calculator ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the generic implementation of LoopInfo used for both Loops and
+// MachineLoops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
+#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/ADT/PostOrderIterator.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// APIs for simple analysis of the loop. See header notes.
+
+/// getExitingBlocks - Return all blocks inside the loop that have successors
+/// outside of the loop. These are the blocks _inside of the current loop_
+/// which branch out. The returned list is always unique.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) {
+ // Not in current loop? It must be an exit block.
+ ExitingBlocks.push_back(*BI);
+ break;
+ }
+}
+
+/// getExitingBlock - If getExitingBlocks would return exactly one block,
+/// return that block. Otherwise return null.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const {
+ SmallVector<BlockT*, 8> ExitingBlocks;
+ getExitingBlocks(ExitingBlocks);
+ if (ExitingBlocks.size() == 1)
+ return ExitingBlocks[0];
+ return 0;
+}
+
+/// getExitBlocks - Return all of the successor blocks of this loop. These
+/// are the blocks _outside of the current loop_ which are branched to.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitBlocks.push_back(*I);
+}
+
+/// getExitBlock - If getExitBlocks would return exactly one block,
+/// return that block. Otherwise return null.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const {
+ SmallVector<BlockT*, 8> ExitBlocks;
+ getExitBlocks(ExitBlocks);
+ if (ExitBlocks.size() == 1)
+ return ExitBlocks[0];
+ return 0;
+}
+
+/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ array_pod_sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitEdges.push_back(Edge(*BI, *I));
+}
+
+/// getLoopPreheader - If there is a preheader for this loop, return it. A
+/// loop has a preheader if there is only one edge to the header of the loop
+/// from outside of the loop. If this is the case, the block branching to the
+/// header of the loop is the preheader node.
+///
+/// This method returns null if there is no preheader for the loop.
+///
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const {
+ // Keep track of nodes outside the loop branching to the header...
+ BlockT *Out = getLoopPredecessor();
+ if (!Out) return 0;
+
+ // Make sure there is only one exit out of the preheader.
+ typedef GraphTraits<BlockT*> BlockTraits;
+ typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
+ ++SI;
+ if (SI != BlockTraits::child_end(Out))
+ return 0; // Multiple exits from the block, must not be a preheader.
+
+ // The predecessor has exactly one successor, so it is a preheader.
+ return Out;
+}
+
+/// getLoopPredecessor - If the given loop's header has exactly one unique
+/// predecessor outside the loop, return it. Otherwise return null.
+/// This is less strict that the loop "preheader" concept, which requires
+/// the predecessor to have exactly one successor.
+///
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
+ // Keep track of nodes outside the loop branching to the header...
+ BlockT *Out = 0;
+
+ // Loop over the predecessors of the header node...
+ BlockT *Header = getHeader();
+ typedef GraphTraits<BlockT*> BlockTraits;
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(Header),
+ PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
+ typename InvBlockTraits::NodeType *N = *PI;
+ if (!contains(N)) { // If the block is not in the loop...
+ if (Out && Out != N)
+ return 0; // Multiple predecessors outside the loop
+ Out = N;
+ }
+ }
+
+ // Make sure there is only one exit out of the preheader.
+ assert(Out && "Header of loop has no predecessors from outside loop?");
+ return Out;
+}
+
+/// getLoopLatch - If there is a single latch block for this loop, return it.
+/// A latch block is a block that contains a branch back to the header.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const {
+ BlockT *Header = getHeader();
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(Header);
+ typename InvBlockTraits::ChildIteratorType PE =
+ InvBlockTraits::child_end(Header);
+ BlockT *Latch = 0;
+ for (; PI != PE; ++PI) {
+ typename InvBlockTraits::NodeType *N = *PI;
+ if (contains(N)) {
+ if (Latch) return 0;
+ Latch = N;
+ }
+ }
+
+ return Latch;
+}
+
+//===----------------------------------------------------------------------===//
+// APIs for updating loop information after changing the CFG
+//
+
+/// addBasicBlockToLoop - This method is used by other analyses to update loop
+/// information. NewBB is set to be a new member of the current loop.
+/// Because of this, it is added as a member of all parent loops, and is added
+/// to the specified LoopInfo object as being in the current basic block. It
+/// is not valid to replace the loop header with this method.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) {
+ assert((Blocks.empty() || LIB[getHeader()] == this) &&
+ "Incorrect LI specified for this loop!");
+ assert(NewBB && "Cannot add a null basic block to the loop!");
+ assert(LIB[NewBB] == 0 && "BasicBlock already in the loop!");
+
+ LoopT *L = static_cast<LoopT *>(this);
+
+ // Add the loop mapping to the LoopInfo object...
+ LIB.BBMap[NewBB] = L;
+
+ // Add the basic block to this loop and all parent loops...
+ while (L) {
+ L->Blocks.push_back(NewBB);
+ L = L->getParentLoop();
+ }
+}
+
+/// replaceChildLoopWith - This is used when splitting loops up. It replaces
+/// the OldChild entry in our children list with NewChild, and updates the
+/// parent pointer of OldChild to be null and the NewChild to be this loop.
+/// This updates the loop depth of the new child.
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild) {
+ assert(OldChild->ParentLoop == this && "This loop is already broken!");
+ assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
+ typename std::vector<LoopT *>::iterator I =
+ std::find(SubLoops.begin(), SubLoops.end(), OldChild);
+ assert(I != SubLoops.end() && "OldChild not in loop!");
+ *I = NewChild;
+ OldChild->ParentLoop = 0;
+ NewChild->ParentLoop = static_cast<LoopT *>(this);
+}
+
+/// verifyLoop - Verify loop structure
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::verifyLoop() const {
+#ifndef NDEBUG
+ assert(!Blocks.empty() && "Loop header is missing");
+
+ // Setup for using a depth-first iterator to visit every block in the loop.
+ SmallVector<BlockT*, 8> ExitBBs;
+ getExitBlocks(ExitBBs);
+ llvm::SmallPtrSet<BlockT*, 8> VisitSet;
+ VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
+ df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
+ BI = df_ext_begin(getHeader(), VisitSet),
+ BE = df_ext_end(getHeader(), VisitSet);
+
+ // Keep track of the number of BBs visited.
+ unsigned NumVisited = 0;
+
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ // Check the individual blocks.
+ for ( ; BI != BE; ++BI) {
+ BlockT *BB = *BI;
+ bool HasInsideLoopSuccs = false;
+ bool HasInsideLoopPreds = false;
+ SmallVector<BlockT *, 2> OutsideLoopPreds;
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (typename BlockTraits::ChildIteratorType SI =
+ BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
+ SI != SE; ++SI)
+ if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *SI)) {
+ HasInsideLoopSuccs = true;
+ break;
+ }
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
+ PI != PE; ++PI) {
+ BlockT *N = *PI;
+ if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N))
+ HasInsideLoopPreds = true;
+ else
+ OutsideLoopPreds.push_back(N);
+ }
+
+ if (BB == getHeader()) {
+ assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
+ } else if (!OutsideLoopPreds.empty()) {
+ // A non-header loop shouldn't be reachable from outside the loop,
+ // though it is permitted if the predecessor is not itself actually
+ // reachable.
+ BlockT *EntryBB = BB->getParent()->begin();
+ for (df_iterator<BlockT *> NI = df_begin(EntryBB),
+ NE = df_end(EntryBB); NI != NE; ++NI)
+ for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
+ assert(*NI != OutsideLoopPreds[i] &&
+ "Loop has multiple entry points!");
+ }
+ assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!");
+ assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
+ assert(BB != getHeader()->getParent()->begin() &&
+ "Loop contains function entry block!");
+
+ NumVisited++;
+ }
+
+ assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
+
+ // Check the subloops.
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ // Each block in each subloop should be contained within this loop.
+ for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
+ BI != BE; ++BI) {
+ assert(std::binary_search(LoopBBs.begin(), LoopBBs.end(), *BI) &&
+ "Loop does not contain all the blocks of a subloop!");
+ }
+
+ // Check the parent loop pointer.
+ if (ParentLoop) {
+ assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) !=
+ ParentLoop->end() &&
+ "Loop is not a subloop of its parent!");
+ }
+#endif
+}
+
+/// verifyLoop - Verify loop structure of this loop and all nested loops.
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::verifyLoopNest(
+ DenseSet<const LoopT*> *Loops) const {
+ Loops->insert(static_cast<const LoopT *>(this));
+ // Verify this loop.
+ verifyLoop();
+ // Verify the subloops.
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (*I)->verifyLoopNest(Loops);
+}
+
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const {
+ OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
+ << " containing: ";
+
+ for (unsigned i = 0; i < getBlocks().size(); ++i) {
+ if (i) OS << ",";
+ BlockT *BB = getBlocks()[i];
+ WriteAsOperand(OS, BB, false);
+ if (BB == getHeader()) OS << "<header>";
+ if (BB == getLoopLatch()) OS << "<latch>";
+ if (isLoopExiting(BB)) OS << "<exiting>";
+ }
+ OS << "\n";
+
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (*I)->print(OS, Depth+2);
+}
+
+//===----------------------------------------------------------------------===//
+/// Stable LoopInfo Analysis - Build a loop tree using stable iterators so the
+/// result does / not depend on use list (block predecessor) order.
+///
+
+/// Discover a subloop with the specified backedges such that: All blocks within
+/// this loop are mapped to this loop or a subloop. And all subloops within this
+/// loop have their parent loop set to this loop or a subloop.
+template<class BlockT, class LoopT>
+static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
+ LoopInfoBase<BlockT, LoopT> *LI,
+ DominatorTreeBase<BlockT> &DomTree) {
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+
+ unsigned NumBlocks = 0;
+ unsigned NumSubloops = 0;
+
+ // Perform a backward CFG traversal using a worklist.
+ std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end());
+ while (!ReverseCFGWorklist.empty()) {
+ BlockT *PredBB = ReverseCFGWorklist.back();
+ ReverseCFGWorklist.pop_back();
+
+ LoopT *Subloop = LI->getLoopFor(PredBB);
+ if (!Subloop) {
+ if (!DomTree.isReachableFromEntry(PredBB))
+ continue;
+
+ // This is an undiscovered block. Map it to the current loop.
+ LI->changeLoopFor(PredBB, L);
+ ++NumBlocks;
+ if (PredBB == L->getHeader())
+ continue;
+ // Push all block predecessors on the worklist.
+ ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
+ InvBlockTraits::child_begin(PredBB),
+ InvBlockTraits::child_end(PredBB));
+ }
+ else {
+ // This is a discovered block. Find its outermost discovered loop.
+ while (LoopT *Parent = Subloop->getParentLoop())
+ Subloop = Parent;
+
+ // If it is already discovered to be a subloop of this loop, continue.
+ if (Subloop == L)
+ continue;
+
+ // Discover a subloop of this loop.
+ Subloop->setParentLoop(L);
+ ++NumSubloops;
+ NumBlocks += Subloop->getBlocks().capacity();
+ PredBB = Subloop->getHeader();
+ // Continue traversal along predecessors that are not loop-back edges from
+ // within this subloop tree itself. Note that a predecessor may directly
+ // reach another subloop that is not yet discovered to be a subloop of
+ // this loop, which we must traverse.
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(PredBB),
+ PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) {
+ if (LI->getLoopFor(*PI) != Subloop)
+ ReverseCFGWorklist.push_back(*PI);
+ }
+ }
+ }
+ L->getSubLoopsVector().reserve(NumSubloops);
+ L->getBlocksVector().reserve(NumBlocks);
+}
+
+namespace {
+/// Populate all loop data in a stable order during a single forward DFS.
+template<class BlockT, class LoopT>
+class PopulateLoopsDFS {
+ typedef GraphTraits<BlockT*> BlockTraits;
+ typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
+ LoopInfoBase<BlockT, LoopT> *LI;
+ DenseSet<const BlockT *> VisitedBlocks;
+ std::vector<std::pair<BlockT*, SuccIterTy> > DFSStack;
+
+public:
+ PopulateLoopsDFS(LoopInfoBase<BlockT, LoopT> *li):
+ LI(li) {}
+
+ void traverse(BlockT *EntryBlock);
+
+protected:
+ void insertIntoLoop(BlockT *Block);
+
+ BlockT *dfsSource() { return DFSStack.back().first; }
+ SuccIterTy &dfsSucc() { return DFSStack.back().second; }
+ SuccIterTy dfsSuccEnd() { return BlockTraits::child_end(dfsSource()); }
+
+ void pushBlock(BlockT *Block) {
+ DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block)));
+ }
+};
+} // anonymous
+
+/// Top-level driver for the forward DFS within the loop.
+template<class BlockT, class LoopT>
+void PopulateLoopsDFS<BlockT, LoopT>::traverse(BlockT *EntryBlock) {
+ pushBlock(EntryBlock);
+ VisitedBlocks.insert(EntryBlock);
+ while (!DFSStack.empty()) {
+ // Traverse the leftmost path as far as possible.
+ while (dfsSucc() != dfsSuccEnd()) {
+ BlockT *BB = *dfsSucc();
+ ++dfsSucc();
+ if (!VisitedBlocks.insert(BB).second)
+ continue;
+
+ // Push the next DFS successor onto the stack.
+ pushBlock(BB);
+ }
+ // Visit the top of the stack in postorder and backtrack.
+ insertIntoLoop(dfsSource());
+ DFSStack.pop_back();
+ }
+}
+
+/// Add a single Block to its ancestor loops in PostOrder. If the block is a
+/// subloop header, add the subloop to its parent in PostOrder, then reverse the
+/// Block and Subloop vectors of the now complete subloop to achieve RPO.
+template<class BlockT, class LoopT>
+void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
+ LoopT *Subloop = LI->getLoopFor(Block);
+ if (Subloop && Block == Subloop->getHeader()) {
+ // We reach this point once per subloop after processing all the blocks in
+ // the subloop.
+ if (Subloop->getParentLoop())
+ Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
+ else
+ LI->addTopLevelLoop(Subloop);
+
+ // For convenience, Blocks and Subloops are inserted in postorder. Reverse
+ // the lists, except for the loop header, which is always at the beginning.
+ std::reverse(Subloop->getBlocksVector().begin()+1,
+ Subloop->getBlocksVector().end());
+ std::reverse(Subloop->getSubLoopsVector().begin(),
+ Subloop->getSubLoopsVector().end());
+
+ Subloop = Subloop->getParentLoop();
+ }
+ for (; Subloop; Subloop = Subloop->getParentLoop())
+ Subloop->getBlocksVector().push_back(Block);
+}
+
+/// Analyze LoopInfo discovers loops during a postorder DominatorTree traversal
+/// interleaved with backward CFG traversals within each subloop
+/// (discoverAndMapSubloop). The backward traversal skips inner subloops, so
+/// this part of the algorithm is linear in the number of CFG edges. Subloop and
+/// Block vectors are then populated during a single forward CFG traversal
+/// (PopulateLoopDFS).
+///
+/// During the two CFG traversals each block is seen three times:
+/// 1) Discovered and mapped by a reverse CFG traversal.
+/// 2) Visited during a forward DFS CFG traversal.
+/// 3) Reverse-inserted in the loop in postorder following forward DFS.
+///
+/// The Block vectors are inclusive, so step 3 requires loop-depth number of
+/// insertions per block.
+template<class BlockT, class LoopT>
+void LoopInfoBase<BlockT, LoopT>::
+Analyze(DominatorTreeBase<BlockT> &DomTree) {
+
+ // Postorder traversal of the dominator tree.
+ DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode();
+ for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot),
+ DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) {
+
+ BlockT *Header = DomIter->getBlock();
+ SmallVector<BlockT *, 4> Backedges;
+
+ // Check each predecessor of the potential loop header.
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(Header),
+ PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
+
+ BlockT *Backedge = *PI;
+
+ // If Header dominates predBB, this is a new loop. Collect the backedges.
+ if (DomTree.dominates(Header, Backedge)
+ && DomTree.isReachableFromEntry(Backedge)) {
+ Backedges.push_back(Backedge);
+ }
+ }
+ // Perform a backward CFG traversal to discover and map blocks in this loop.
+ if (!Backedges.empty()) {
+ LoopT *L = new LoopT(Header);
+ discoverAndMapSubloop(L, ArrayRef<BlockT*>(Backedges), this, DomTree);
+ }
+ }
+ // Perform a single forward CFG traversal to populate block and subloop
+ // vectors for all loops.
+ PopulateLoopsDFS<BlockT, LoopT> DFS(this);
+ DFS.traverse(DomRoot->getBlock());
+}
+
+// Debugging
+template<class BlockT, class LoopT>
+void LoopInfoBase<BlockT, LoopT>::print(raw_ostream &OS) const {
+ for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
+ TopLevelLoops[i]->print(OS);
+#if 0
+ for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
+ E = BBMap.end(); I != E; ++I)
+ OS << "BB '" << I->first->getName() << "' level = "
+ << I->second->getLoopDepth() << "\n";
+#endif
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h
index 269ac8074054..68f25f74bc28 100644
--- a/include/llvm/Analysis/LoopIterator.h
+++ b/include/llvm/Analysis/LoopIterator.h
@@ -109,6 +109,16 @@ public:
}
};
+/// Specialize po_iterator_storage to record postorder numbers.
+template<> class po_iterator_storage<LoopBlocksTraversal, true> {
+ LoopBlocksTraversal &LBT;
+public:
+ po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {}
+ // These functions are defined below.
+ bool insertEdge(BasicBlock *From, BasicBlock *To);
+ void finishPostorder(BasicBlock *BB);
+};
+
/// Traverse the blocks in a loop using a depth-first search.
class LoopBlocksTraversal {
public:
@@ -155,31 +165,17 @@ public:
DFS.PostBlocks.push_back(BB);
DFS.PostNumbers[BB] = DFS.PostBlocks.size();
}
-
- //===----------------------------------------------------------------------
- // Implement part of the std::set interface for the purpose of driving the
- // generic po_iterator.
-
- /// Return true if the block is outside the loop or has already been visited.
- /// Sorry if this is counterintuitive.
- bool count(BasicBlock *BB) const {
- return !DFS.L->contains(LI->getLoopFor(BB)) || DFS.PostNumbers.count(BB);
- }
-
- /// If this block is contained in the loop and has not been visited, return
- /// true and assign a preorder number. This is a proxy for visitPreorder
- /// called by POIterator.
- bool insert(BasicBlock *BB) {
- return visitPreorder(BB);
- }
};
-/// Specialize DFSetTraits to record postorder numbers.
-template<> struct DFSetTraits<LoopBlocksTraversal> {
- static void finishPostorder(BasicBlock *BB, LoopBlocksTraversal& LBT) {
- LBT.finishPostorder(BB);
- }
-};
+inline bool po_iterator_storage<LoopBlocksTraversal, true>::
+insertEdge(BasicBlock *From, BasicBlock *To) {
+ return LBT.visitPreorder(To);
+}
+
+inline void po_iterator_storage<LoopBlocksTraversal, true>::
+finishPostorder(BasicBlock *BB) {
+ LBT.finishPostorder(BB);
+}
} // End namespace llvm
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index 865d236f6f3a..e674e74520d2 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -15,6 +15,15 @@
#ifndef 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/SmallPtrSet.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/TargetFolder.h"
+#include "llvm/Support/ValueHandle.h"
+
namespace llvm {
class CallInst;
class PointerType;
@@ -22,24 +31,44 @@ class TargetData;
class Type;
class Value;
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
+/// like).
+bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a function that returns a
+/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
+bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates uninitialized memory (such as malloc).
+bool isMallocLikeFn(const Value *V, bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates zero-filled memory (such as calloc).
+bool isCallocLikeFn(const Value *V, bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates memory (either malloc, calloc, or strdup like).
+bool isAllocLikeFn(const Value *V, bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// reallocates memory (such as realloc).
+bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
+
+
//===----------------------------------------------------------------------===//
// malloc Call Utility Functions.
//
-/// isMalloc - Returns true if the value is either a malloc call or a bitcast of
-/// the result of a malloc call
-bool isMalloc(const Value *I);
-
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
const CallInst *extractMallocCall(const Value *I);
-CallInst *extractMallocCall(Value *I);
-
-/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
-/// instruction is a bitcast of the result of a malloc call.
-const CallInst *extractMallocCallFromBitCast(const Value *I);
-CallInst *extractMallocCallFromBitCast(Value *I);
+static inline CallInst *extractMallocCall(Value *I) {
+ return const_cast<CallInst*>(extractMallocCall((const Value*)I));
+}
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
@@ -67,7 +96,20 @@ Type *getMallocAllocatedType(const CallInst *CI);
/// determined.
Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
bool LookThroughSExt = false);
-
+
+
+//===----------------------------------------------------------------------===//
+// calloc Call Utility Functions.
+//
+
+/// extractCallocCall - Returns the corresponding CallInst if the instruction
+/// is a calloc call.
+const CallInst *extractCallocCall(const Value *I);
+static inline CallInst *extractCallocCall(Value *I) {
+ return const_cast<CallInst*>(extractCallocCall((const Value*)I));
+}
+
+
//===----------------------------------------------------------------------===//
// free Call Utility Functions.
//
@@ -79,6 +121,131 @@ static inline CallInst *isFreeCall(Value *I) {
return const_cast<CallInst*>(isFreeCall((const Value*)I));
}
+
+//===----------------------------------------------------------------------===//
+// Utility functions to compute size of objects.
+//
+
+/// \brief Compute the size of the object pointed by Ptr. Returns true and the
+/// object size in Size if successful, and false otherwise.
+/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
+/// byval arguments, and global variables.
+bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
+ bool RoundToAlign = false);
+
+
+
+typedef std::pair<APInt, APInt> SizeOffsetType;
+
+/// \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.
+class ObjectSizeOffsetVisitor
+ : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
+
+ const TargetData *TD;
+ bool RoundToAlign;
+ unsigned IntTyBits;
+ APInt Zero;
+
+ APInt align(APInt Size, uint64_t Align);
+
+ SizeOffsetType unknown() {
+ return std::make_pair(APInt(), APInt());
+ }
+
+public:
+ ObjectSizeOffsetVisitor(const TargetData *TD, LLVMContext &Context,
+ bool RoundToAlign = false);
+
+ SizeOffsetType compute(Value *V);
+
+ bool knownSize(SizeOffsetType &SizeOffset) {
+ return SizeOffset.first.getBitWidth() > 1;
+ }
+
+ bool knownOffset(SizeOffsetType &SizeOffset) {
+ return SizeOffset.second.getBitWidth() > 1;
+ }
+
+ bool bothKnown(SizeOffsetType &SizeOffset) {
+ return knownSize(SizeOffset) && knownOffset(SizeOffset);
+ }
+
+ SizeOffsetType visitAllocaInst(AllocaInst &I);
+ SizeOffsetType visitArgument(Argument &A);
+ SizeOffsetType visitCallSite(CallSite CS);
+ SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
+ SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
+ SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
+ SizeOffsetType visitGEPOperator(GEPOperator &GEP);
+ SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
+ SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
+ SizeOffsetType visitLoadInst(LoadInst &I);
+ SizeOffsetType visitPHINode(PHINode&);
+ SizeOffsetType visitSelectInst(SelectInst &I);
+ SizeOffsetType visitUndefValue(UndefValue&);
+ SizeOffsetType visitInstruction(Instruction &I);
+};
+
+typedef std::pair<Value*, Value*> SizeOffsetEvalType;
+
+
+/// \brief Evaluate the size and offset of an object ponted by a Value*.
+/// May create code to compute the result at run-time.
+class ObjectSizeOffsetEvaluator
+ : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
+
+ typedef IRBuilder<true, TargetFolder> BuilderTy;
+ typedef std::pair<WeakVH, WeakVH> WeakEvalType;
+ typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
+ typedef SmallPtrSet<const Value*, 8> PtrSetTy;
+
+ const TargetData *TD;
+ LLVMContext &Context;
+ BuilderTy Builder;
+ ObjectSizeOffsetVisitor Visitor;
+ IntegerType *IntTy;
+ Value *Zero;
+ CacheMapTy CacheMap;
+ PtrSetTy SeenVals;
+
+ SizeOffsetEvalType unknown() {
+ return std::make_pair((Value*)0, (Value*)0);
+ }
+ SizeOffsetEvalType compute_(Value *V);
+
+public:
+ ObjectSizeOffsetEvaluator(const TargetData *TD, LLVMContext &Context);
+ SizeOffsetEvalType compute(Value *V);
+
+ bool knownSize(SizeOffsetEvalType SizeOffset) {
+ return SizeOffset.first;
+ }
+
+ bool knownOffset(SizeOffsetEvalType SizeOffset) {
+ return SizeOffset.second;
+ }
+
+ bool anyKnown(SizeOffsetEvalType SizeOffset) {
+ return knownSize(SizeOffset) || knownOffset(SizeOffset);
+ }
+
+ bool bothKnown(SizeOffsetEvalType SizeOffset) {
+ return knownSize(SizeOffset) && knownOffset(SizeOffset);
+ }
+
+ SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
+ SizeOffsetEvalType visitCallSite(CallSite CS);
+ SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
+ SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
+ SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
+ SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
+ SizeOffsetEvalType visitLoadInst(LoadInst &I);
+ SizeOffsetEvalType visitPHINode(PHINode &PHI);
+ SizeOffsetEvalType visitSelectInst(SelectInst &I);
+ SizeOffsetEvalType visitInstruction(Instruction &I);
+};
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 68ce364f4413..7e049d633b49 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -124,11 +124,11 @@ namespace llvm {
}
/// isClobber - Return true if this MemDepResult represents a query that is
- /// a instruction clobber dependency.
+ /// an instruction clobber dependency.
bool isClobber() const { return Value.getInt() == Clobber; }
/// isDef - Return true if this MemDepResult represents a query that is
- /// a instruction definition dependency.
+ /// an instruction definition dependency.
bool isDef() const { return Value.getInt() == Def; }
/// isNonLocal - Return true if this MemDepResult represents a query that
@@ -431,9 +431,6 @@ namespace llvm {
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
- AliasAnalysis::ModRefResult
- getModRefInfo(const Instruction *Inst, const AliasAnalysis::Location &Loc);
-
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;
diff --git a/include/llvm/Analysis/ProfileInfoLoader.h b/include/llvm/Analysis/ProfileInfoLoader.h
index 9e0c393c428f..dcf3b38ddcd5 100644
--- a/include/llvm/Analysis/ProfileInfoLoader.h
+++ b/include/llvm/Analysis/ProfileInfoLoader.h
@@ -28,19 +28,16 @@ class BasicBlock;
class ProfileInfoLoader {
const std::string &Filename;
- Module &M;
std::vector<std::string> CommandLines;
std::vector<unsigned> FunctionCounts;
std::vector<unsigned> BlockCounts;
std::vector<unsigned> EdgeCounts;
std::vector<unsigned> OptimalEdgeCounts;
std::vector<unsigned> BBTrace;
- bool Warned;
public:
// ProfileInfoLoader ctor - Read the specified profiling data file, exiting
// the program if the file is invalid or broken.
- ProfileInfoLoader(const char *ToolName, const std::string &Filename,
- Module &M);
+ ProfileInfoLoader(const char *ToolName, const std::string &Filename);
static const unsigned Uncounted;
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index b098eeaa3db8..188d11c2833c 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -473,25 +473,85 @@ public:
const_iterator end() const { return children.end(); }
//@}
- /// @name BasicBlock Iterators
+ /// @name BasicBlock Node Iterators
///
/// These iterators iterate over all BasicBlock RegionNodes that are
- /// contained in this Region. The iterator also iterates over BasicBlocks
- /// that are elements of a subregion of this Region. It is therefore called a
- /// flat iterator.
+ /// contained in this Region. The iterator also iterates over BasicBlock
+ /// RegionNodes that are elements of a subregion of this Region. It is
+ /// therefore called a flat iterator.
//@{
typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
- GraphTraits<FlatIt<RegionNode*> > > block_iterator;
+ GraphTraits<FlatIt<RegionNode*> > > block_node_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<FlatIt<const RegionNode*> > >
- const_block_iterator;
+ const_block_node_iterator;
+
+ block_node_iterator block_node_begin();
+ block_node_iterator block_node_end();
+
+ const_block_node_iterator block_node_begin() const;
+ const_block_node_iterator block_node_end() const;
+ //@}
+
+ /// @name BasicBlock Iterators
+ ///
+ /// These iterators iterate over all BasicBlocks that are contained in this
+ /// Region. The iterator also iterates over BasicBlocks that are elements of
+ /// a subregion of this Region. It is therefore called a flat iterator.
+ //@{
+ template <bool IsConst>
+ class block_iterator_wrapper
+ : public df_iterator<typename conditional<IsConst,
+ const BasicBlock,
+ BasicBlock>::type*> {
+ typedef df_iterator<typename conditional<IsConst,
+ const BasicBlock,
+ BasicBlock>::type*>
+ super;
+ public:
+ typedef block_iterator_wrapper<IsConst> Self;
+ typedef typename super::pointer pointer;
+
+ // Construct the begin iterator.
+ block_iterator_wrapper(pointer Entry, pointer Exit) : super(df_begin(Entry))
+ {
+ // Mark the exit of the region as visited, so that the children of the
+ // exit and the exit itself, i.e. the block outside the region will never
+ // be visited.
+ super::Visited.insert(Exit);
+ }
+
+ // Construct the end iterator.
+ block_iterator_wrapper() : super(df_end<pointer>((BasicBlock *)0)) {}
+
+ /*implicit*/ block_iterator_wrapper(super I) : super(I) {}
+
+ // FIXME: Even a const_iterator returns a non-const BasicBlock pointer.
+ // This was introduced for backwards compatibility, but should
+ // be removed as soon as all users are fixed.
+ BasicBlock *operator*() const {
+ return const_cast<BasicBlock*>(super::operator*());
+ }
+ };
+
+ typedef block_iterator_wrapper<false> block_iterator;
+ typedef block_iterator_wrapper<true> const_block_iterator;
+
+ block_iterator block_begin() {
+ return block_iterator(getEntry(), getExit());
+ }
- block_iterator block_begin();
- block_iterator block_end();
+ block_iterator block_end() {
+ return block_iterator();
+ }
- const_block_iterator block_begin() const;
- const_block_iterator block_end() const;
+ const_block_iterator block_begin() const {
+ return const_block_iterator(getEntry(), getExit());
+ }
+ const_block_iterator block_end() const {
+ return const_block_iterator();
+ }
//@}
/// @name Element Iterators
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 72408f773840..c213ade5e8e3 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -30,7 +30,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include <map>
namespace llvm {
@@ -250,6 +250,9 @@ namespace llvm {
///
ValueExprMapType ValueExprMap;
+ /// Mark predicate values currently being processed by isImpliedCond.
+ DenseSet<Value*> PendingLoopPredicates;
+
/// ExitLimit - Information about the number of loop iterations for
/// which a loop exit's branch condition evaluates to the not-taken path.
/// This is a temporary pair of exact and max expressions that are
@@ -834,7 +837,8 @@ namespace llvm {
///
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
const SCEV *&LHS,
- const SCEV *&RHS);
+ const SCEV *&RHS,
+ unsigned Depth = 0);
/// getLoopDisposition - Return the "disposition" of the given SCEV with
/// respect to the given loop.
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index c22fc3ab74b7..3f8f149cb420 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -14,9 +14,9 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+#include "llvm/IRBuilder.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
#include <set>
@@ -24,6 +24,10 @@
namespace llvm {
class TargetLowering;
+ /// Return true if the given expression is safe to expand in the sense that
+ /// all materialized values are safe to speculate.
+ bool isSafeToExpand(const SCEV *S);
+
/// SCEVExpander - This class uses information about analyze scalars to
/// rewrite expressions in canonical form.
///
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 47b371029186..ded12974face 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -15,6 +15,7 @@
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -493,6 +494,74 @@ namespace llvm {
llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
}
};
+
+ /// Visit all nodes in the expression tree using worklist traversal.
+ ///
+ /// Visitor implements:
+ /// // return true to follow this node.
+ /// bool follow(const SCEV *S);
+ /// // return true to terminate the search.
+ /// bool isDone();
+ template<typename SV>
+ class SCEVTraversal {
+ SV &Visitor;
+ SmallVector<const SCEV *, 8> Worklist;
+ SmallPtrSet<const SCEV *, 8> Visited;
+
+ void push(const SCEV *S) {
+ if (Visited.insert(S) && Visitor.follow(S))
+ Worklist.push_back(S);
+ }
+ public:
+ SCEVTraversal(SV& V): Visitor(V) {}
+
+ void visitAll(const SCEV *Root) {
+ push(Root);
+ while (!Worklist.empty() && !Visitor.isDone()) {
+ const SCEV *S = Worklist.pop_back_val();
+
+ switch (S->getSCEVType()) {
+ case scConstant:
+ case scUnknown:
+ break;
+ case scTruncate:
+ case scZeroExtend:
+ case scSignExtend:
+ push(cast<SCEVCastExpr>(S)->getOperand());
+ break;
+ case scAddExpr:
+ case scMulExpr:
+ case scSMaxExpr:
+ case scUMaxExpr:
+ case scAddRecExpr: {
+ const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
+ for (SCEVNAryExpr::op_iterator I = NAry->op_begin(),
+ E = NAry->op_end(); I != E; ++I) {
+ push(*I);
+ }
+ break;
+ }
+ case scUDivExpr: {
+ const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
+ push(UDiv->getLHS());
+ push(UDiv->getRHS());
+ break;
+ }
+ case scCouldNotCompute:
+ llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
+ default:
+ llvm_unreachable("Unknown SCEV kind!");
+ }
+ }
+ }
+ };
+
+ /// Use SCEVTraversal to visit all nodes in the givien expression tree.
+ template<typename SV>
+ void visitAll(const SCEV *Root, SV& Visitor) {
+ SCEVTraversal<SV> T(Visitor);
+ T.visitAll(Root);
+ }
}
#endif
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index f2f9db4ce4e8..e8d45f6bb8d4 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -151,6 +151,14 @@ namespace llvm {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
+ /// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
+ /// except that it can look through phi and select instructions and return
+ /// multiple objects.
+ void GetUnderlyingObjects(Value *V,
+ SmallVectorImpl<Value *> &Objects,
+ const TargetData *TD = 0,
+ unsigned MaxLookup = 6);
+
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 0099f173b626..223aa0063906 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -16,6 +16,7 @@
#define LLVM_ATTRIBUTES_H
#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/ArrayRef.h"
#include <cassert>
#include <string>
@@ -45,14 +46,9 @@ class Attributes {
Attributes() : Bits(0) { }
explicit Attributes(uint64_t Val) : Bits(Val) { }
/*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
- Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { }
// This is a "safe bool() operator".
operator const void *() const { return Bits ? this : 0; }
bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
- Attributes &operator = (const Attributes &Attrs) {
- Bits = Attrs.Bits;
- return *this;
- }
bool operator == (const Attributes &Attrs) const {
return Bits == Attrs.Bits;
}
@@ -138,6 +134,9 @@ DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on.
+DECLARE_LLVM_ATTRIBUTE(IANSDialect,1ULL<<33) ///< Inline asm non-standard dialect.
+ /// When not set, ATT dialect assumed.
+ /// When set implies the Intel dialect.
#undef DECLARE_LLVM_ATTRIBUTE
@@ -163,14 +162,16 @@ const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
Naked_i | InlineHint_i | StackAlignment_i |
- UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
+ UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i |
+ IANSDialect_i};
/// @brief Parameter attributes that do not apply to vararg call arguments.
const AttrConst VarArgsIncompatible = {StructRet_i};
/// @brief Attributes that are mutually incompatible.
-const AttrConst MutuallyIncompatible[4] = {
- {ByVal_i | InReg_i | Nest_i | StructRet_i},
+const AttrConst MutuallyIncompatible[5] = {
+ {ByVal_i | Nest_i | StructRet_i},
+ {ByVal_i | Nest_i | InReg_i },
{ZExt_i | SExt_i},
{ReadNone_i | ReadOnly_i},
{NoInline_i | AlwaysInline_i}
@@ -222,6 +223,50 @@ inline unsigned getStackAlignmentFromAttrs(Attributes A) {
return 1U << ((StackAlign.Raw() >> 26) - 1);
}
+/// This returns an integer containing an encoding of all the
+/// LLVM attributes found in the given attribute bitset. Any
+/// change to this encoding is a breaking change to bitcode
+/// compatibility.
+inline uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
+ // FIXME: It doesn't make sense to store the alignment information as an
+ // expanded out value, we should store it as a log2 value. However, we can't
+ // just change that here without breaking bitcode compatibility. If this ever
+ // becomes a problem in practice, we should introduce new tag numbers in the
+ // bitcode file and have those tags use a more efficiently encoded alignment
+ // field.
+
+ // Store the alignment in the bitcode as a 16-bit raw value instead of a
+ // 5-bit log2 encoded value. Shift the bits above the alignment up by
+ // 11 bits.
+
+ uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
+ if (Attrs & Attribute::Alignment)
+ EncodedAttrs |= (1ull << 16) <<
+ (((Attrs & Attribute::Alignment).Raw()-1) >> 16);
+ EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
+
+ return EncodedAttrs;
+}
+
+/// 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'.
+inline Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
+ // The alignment is stored as a 16-bit raw value from bits 31--16.
+ // We shift the bits above 31 down by 11 bits.
+
+ unsigned Alignment = (EncodedAttrs & (0xffffull << 16)) >> 16;
+ assert((!Alignment || isPowerOf2_32(Alignment)) &&
+ "Alignment must be a power of two.");
+
+ Attributes Attrs(EncodedAttrs & 0xffff);
+ if (Alignment)
+ Attrs |= Attribute::constructAlignmentFromInt(Alignment);
+ Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
+
+ return Attrs;
+}
+
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
@@ -268,16 +313,8 @@ public:
// Attribute List Construction and Mutation
//===--------------------------------------------------------------------===//
- /// get - Return a Attributes list with the specified parameter in it.
- static AttrListPtr get(const AttributeWithIndex *Attr, unsigned NumAttrs);
-
- /// get - Return a Attribute list with the parameters specified by the
- /// consecutive random access iterator range.
- template <typename Iter>
- static AttrListPtr get(const Iter &I, const Iter &E) {
- if (I == E) return AttrListPtr(); // Empty list.
- return get(&*I, static_cast<unsigned>(E-I));
- }
+ /// get - Return a Attributes list with the specified parameters in it.
+ static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs);
/// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
index 86c44c7f150b..3c75e5882dbd 100644
--- a/include/llvm/Bitcode/Archive.h
+++ b/include/llvm/Bitcode/Archive.h
@@ -47,14 +47,13 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
/// characteristics of the member. The various "is" methods below provide
/// access to the flags. The flags are not user settable.
enum Flags {
- CompressedFlag = 1, ///< Member is a normal compressed file
- SVR4SymbolTableFlag = 2, ///< Member is a SVR4 symbol table
- BSD4SymbolTableFlag = 4, ///< Member is a BSD4 symbol table
- LLVMSymbolTableFlag = 8, ///< Member is an LLVM symbol table
- BitcodeFlag = 16, ///< Member is bitcode
- HasPathFlag = 64, ///< Member has a full or partial path
- HasLongFilenameFlag = 128, ///< Member uses the long filename syntax
- StringTableFlag = 256 ///< Member is an ar(1) format string table
+ SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
+ BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
+ LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table
+ BitcodeFlag = 8, ///< Member is bitcode
+ HasPathFlag = 16, ///< Member has a full or partial path
+ HasLongFilenameFlag = 32, ///< Member uses the long filename syntax
+ StringTableFlag = 64 ///< Member is an ar(1) format string table
};
/// @}
@@ -109,11 +108,6 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
/// @brief Get the data content of the archive member
const char* getData() const { return data; }
- /// This method determines if the member is a regular compressed file.
- /// @returns true iff the archive member is a compressed regular file.
- /// @brief Determine if the member is a compressed regular file.
- bool isCompressed() const { return flags&CompressedFlag; }
-
/// @returns true iff the member is a SVR4 (non-LLVM) symbol table
/// @brief Determine if this member is a SVR4 symbol table.
bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
@@ -427,7 +421,6 @@ class Archive {
bool writeToDisk(
bool CreateSymbolTable=false, ///< Create Symbol table
bool TruncateNames=false, ///< Truncate the filename to 15 chars
- bool Compress=false, ///< Compress files
std::string* ErrMessage=0 ///< If non-null, where error msg is set
);
@@ -494,7 +487,6 @@ class Archive {
std::ofstream& ARFile, ///< The file to write member onto
bool CreateSymbolTable, ///< Should symbol table be created?
bool TruncateNames, ///< Should names be truncated to 11 chars?
- bool ShouldCompress, ///< Should the member be compressed?
std::string* ErrMessage ///< If non-null, place were error msg is set
);
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index cc2b473f2c57..dd96b043fc95 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -71,8 +71,8 @@ namespace llvm {
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
/// for an LLVM IR bitcode wrapper.
///
- static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
- const unsigned char *BufEnd) {
+ inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
// See if you can find the hidden message in the magic bytes :-).
// (Hint: it's a little-endian encoding.)
return BufPtr != BufEnd &&
@@ -85,8 +85,8 @@ namespace llvm {
/// isRawBitcode - Return true if the given bytes are the magic bytes for
/// raw LLVM IR bitcode (without a wrapper).
///
- static inline bool isRawBitcode(const unsigned char *BufPtr,
- const unsigned char *BufEnd) {
+ inline bool isRawBitcode(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
// These bytes sort of have a hidden message, but it's not in
// little-endian this time, and it's a little redundant.
return BufPtr != BufEnd &&
@@ -99,8 +99,8 @@ namespace llvm {
/// isBitcode - Return true if the given bytes are the magic bytes for
/// LLVM IR bitcode, either with or without a wrapper.
///
- static bool inline isBitcode(const unsigned char *BufPtr,
- const unsigned char *BufEnd) {
+ inline bool isBitcode(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
return isBitcodeWrapper(BufPtr, BufEnd) ||
isRawBitcode(BufPtr, BufEnd);
}
@@ -121,9 +121,9 @@ namespace llvm {
/// BC file.
/// If 'VerifyBufferSize' is true, check that the buffer is large enough to
/// contain the whole bitcode file.
- static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
- const unsigned char *&BufEnd,
- bool VerifyBufferSize) {
+ inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
+ const unsigned char *&BufEnd,
+ bool VerifyBufferSize) {
enum {
KnownHeaderSize = 4*4, // Size of header we read.
OffsetField = 2*4, // Offset in bytes to Offset field.
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index de3ff8623cff..f8cb4250584c 100644
--- a/include/llvm/CMakeLists.txt
+++ b/include/llvm/CMakeLists.txt
@@ -6,8 +6,6 @@ add_custom_target(intrinsics_gen ALL
DEPENDS ${llvm_builded_incs_dir}/Intrinsics.gen)
set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")
-set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} intrinsics_gen PARENT_SCOPE)
-
if( MSVC_IDE OR XCODE )
# Creates a dummy target containing all headers for the benefit of
# Visual Studio users.
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 56a87f139a21..170a528a5a22 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -354,6 +354,13 @@ namespace llvm {
void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size) const;
+ /// EmitLabelReference - Emit something like ".long Label"
+ /// where the size in bytes of the directive is specified by Size and Label
+ /// specifies the label.
+ void EmitLabelReference(const MCSymbol *Label, unsigned Size) const {
+ EmitLabelPlusOffset(Label, 0, Size);
+ }
+
//===------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h
index ee1ed0779be4..2d2db78144a4 100644
--- a/include/llvm/CodeGen/DFAPacketizer.h
+++ b/include/llvm/CodeGen/DFAPacketizer.h
@@ -28,6 +28,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/DenseMap.h"
+#include <map>
namespace llvm {
@@ -36,7 +37,7 @@ class MachineInstr;
class MachineLoopInfo;
class MachineDominatorTree;
class InstrItineraryData;
-class ScheduleDAGInstrs;
+class DefaultVLIWScheduler;
class SUnit;
class DFAPacketizer {
@@ -77,6 +78,8 @@ public:
// reserveResources - Reserve the resources occupied by a machine
// instruction and change the current state to reflect that change.
void reserveResources(llvm::MachineInstr *MI);
+
+ const InstrItineraryData *getInstrItins() const { return InstrItins; }
};
// VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
@@ -87,20 +90,21 @@ public:
// and machine resource is marked as taken. If any dependency is found, a target
// API call is made to prune the dependence.
class VLIWPacketizerList {
+protected:
const TargetMachine &TM;
const MachineFunction &MF;
const TargetInstrInfo *TII;
- // Encapsulate data types not exposed to the target interface.
- ScheduleDAGInstrs *SchedulerImpl;
+ // The VLIW Scheduler.
+ DefaultVLIWScheduler *VLIWScheduler;
-protected:
// Vector of instructions assigned to the current packet.
std::vector<MachineInstr*> CurrentPacketMIs;
// DFA resource tracker.
DFAPacketizer *ResourceTracker;
- // Scheduling units.
- std::vector<SUnit> SUnits;
+
+ // Generate MI -> SU map.
+ std::map<MachineInstr*, SUnit*> MIToSUnit;
public:
VLIWPacketizerList(
@@ -118,17 +122,32 @@ public:
DFAPacketizer *getResourceTracker() {return ResourceTracker;}
// addToPacket - Add MI to the current packet.
- void addToPacket(MachineInstr *MI);
+ virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) {
+ MachineBasicBlock::iterator MII = MI;
+ CurrentPacketMIs.push_back(MI);
+ ResourceTracker->reserveResources(MI);
+ return MII;
+ }
// endPacket - End the current packet.
- void endPacket(MachineBasicBlock *MBB, MachineInstr *I);
+ void endPacket(MachineBasicBlock *MBB, MachineInstr *MI);
+
+ // initPacketizerState - perform initialization before packetizing
+ // an instruction. This function is supposed to be overrided by
+ // the target dependent packetizer.
+ virtual void initPacketizerState(void) { return; }
// ignorePseudoInstruction - Ignore bundling of pseudo instructions.
- bool ignorePseudoInstruction(MachineInstr *I, MachineBasicBlock *MBB);
+ virtual bool ignorePseudoInstruction(MachineInstr *I,
+ MachineBasicBlock *MBB) {
+ return false;
+ }
- // isSoloInstruction - return true if instruction I must end previous
- // packet.
- bool isSoloInstruction(MachineInstr *I);
+ // isSoloInstruction - return true if instruction MI can not be packetized
+ // with any other instruction, which means that MI itself is a packet.
+ virtual bool isSoloInstruction(MachineInstr *MI) {
+ return true;
+ }
// isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
// together.
@@ -141,6 +160,7 @@ public:
virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
return false;
}
+
};
}
diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h
index a1d29b1f02c5..e8a4a2d2d894 100644
--- a/include/llvm/CodeGen/EdgeBundles.h
+++ b/include/llvm/CodeGen/EdgeBundles.h
@@ -46,7 +46,7 @@ public:
unsigned getNumBundles() const { return EC.getNumClasses(); }
/// getBlocks - Return an array of blocks that are connected to Bundle.
- ArrayRef<unsigned> getBlocks(unsigned Bundle) { return Blocks[Bundle]; }
+ ArrayRef<unsigned> getBlocks(unsigned Bundle) const { return Blocks[Bundle]; }
/// getMachineFunction - Return the last machine function computed.
const MachineFunction *getMachineFunction() const { return MF; }
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index e57c8b18c63e..7cb96952aa61 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -34,6 +34,7 @@ class MachineFrameInfo;
class MachineRegisterInfo;
class TargetData;
class TargetInstrInfo;
+class TargetLibraryInfo;
class TargetLowering;
class TargetMachine;
class TargetRegisterClass;
@@ -57,6 +58,7 @@ protected:
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;
+ const TargetLibraryInfo *LibInfo;
/// The position of the last instruction for materializing constants
/// for use in the current block. It resets to EmitStartPt when it
@@ -144,7 +146,8 @@ public:
virtual ~FastISel();
protected:
- explicit FastISel(FunctionLoweringInfo &funcInfo);
+ explicit FastISel(FunctionLoweringInfo &funcInfo,
+ const TargetLibraryInfo *libInfo);
/// TargetSelectInstruction - This method is called by target-independent
/// code when the normal FastISel process fails to select an instruction.
@@ -299,6 +302,15 @@ protected:
unsigned Op1, bool Op1IsKill,
uint64_t Imm);
+ /// FastEmitInst_rrii - Emit a MachineInstr with two register operands,
+ /// two immediates operands, and a result register in the given register
+ /// class.
+ unsigned FastEmitInst_rrii(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ uint64_t Imm1, uint64_t Imm2);
+
/// FastEmitInst_i - Emit a MachineInstr with a single immediate
/// operand, and a result register in the given register class.
unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 45469ed7de80..20e33f74f650 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -48,18 +48,18 @@ namespace llvm {
/// PointKind - The type of a collector-safe point.
///
enum PointKind {
- Loop, //< Instr is a loop (backwards branch).
- Return, //< Instr is a return instruction.
- PreCall, //< Instr is a call instruction.
- PostCall //< Instr is the return address of a call.
+ Loop, ///< Instr is a loop (backwards branch).
+ Return, ///< Instr is a return instruction.
+ PreCall, ///< Instr is a call instruction.
+ PostCall ///< Instr is the return address of a call.
};
}
/// GCPoint - Metadata for a collector-safe point in machine code.
///
struct GCPoint {
- GC::PointKind Kind; //< The kind of the safe point.
- MCSymbol *Label; //< A label.
+ GC::PointKind Kind; ///< The kind of the safe point.
+ MCSymbol *Label; ///< A label.
DebugLoc Loc;
GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
@@ -69,9 +69,10 @@ namespace llvm {
/// GCRoot - Metadata for a pointer to an object managed by the garbage
/// collector.
struct GCRoot {
- int Num; //< Usually a frame index.
- int StackOffset; //< Offset from the stack pointer.
- const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot.
+ int Num; ///< Usually a frame index.
+ int StackOffset; ///< Offset from the stack pointer.
+ const Constant *Metadata; ///< Metadata straight from the call
+ ///< to llvm.gcroot.
GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
};
diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h
index 1cbd36abfbf8..dfc26d72dc9f 100644
--- a/include/llvm/CodeGen/GCStrategy.h
+++ b/include/llvm/CodeGen/GCStrategy.h
@@ -65,14 +65,14 @@ namespace llvm {
list_type Functions;
protected:
- unsigned NeededSafePoints; //< Bitmask of required safe points.
- bool CustomReadBarriers; //< Default is to insert loads.
- bool CustomWriteBarriers; //< Default is to insert stores.
- bool CustomRoots; //< Default is to pass through to backend.
- bool CustomSafePoints; //< Default is to use NeededSafePoints
- // to find safe points.
- bool InitRoots; //< If set, roots are nulled during lowering.
- bool UsesMetadata; //< If set, backend must emit metadata tables.
+ unsigned NeededSafePoints; ///< Bitmask of required safe points.
+ bool CustomReadBarriers; ///< Default is to insert loads.
+ bool CustomWriteBarriers; ///< Default is to insert stores.
+ bool CustomRoots; ///< Default is to pass through to backend.
+ bool CustomSafePoints; ///< Default is to use NeededSafePoints
+ ///< to find safe points.
+ bool InitRoots; ///< If set, roots are nulled during lowering.
+ bool UsesMetadata; ///< If set, backend must emit metadata tables.
public:
GCStrategy();
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index ab8ab5dd7b4e..f387bd518f17 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -37,87 +37,87 @@ namespace ISD {
/// and getMachineOpcode() member functions of SDNode.
///
enum NodeType {
- // DELETED_NODE - This is an illegal value that is used to catch
- // errors. This opcode is not a legal opcode for any node.
+ /// DELETED_NODE - This is an illegal value that is used to catch
+ /// errors. This opcode is not a legal opcode for any node.
DELETED_NODE,
- // EntryToken - This is the marker used to indicate the start of the region.
+ /// EntryToken - This is the marker used to indicate the start of a region.
EntryToken,
- // TokenFactor - This node takes multiple tokens as input and produces a
- // single token result. This is used to represent the fact that the operand
- // operators are independent of each other.
+ /// TokenFactor - This node takes multiple tokens as input and produces a
+ /// single token result. This is used to represent the fact that the operand
+ /// operators are independent of each other.
TokenFactor,
- // AssertSext, AssertZext - These nodes record if a register contains a
- // value that has already been zero or sign extended from a narrower type.
- // These nodes take two operands. The first is the node that has already
- // been extended, and the second is a value type node indicating the width
- // of the extension
+ /// AssertSext, AssertZext - These nodes record if a register contains a
+ /// value that has already been zero or sign extended from a narrower type.
+ /// These nodes take two operands. The first is the node that has already
+ /// been extended, and the second is a value type node indicating the width
+ /// of the extension
AssertSext, AssertZext,
- // Various leaf nodes.
+ /// Various leaf nodes.
BasicBlock, VALUETYPE, CONDCODE, Register, RegisterMask,
Constant, ConstantFP,
GlobalAddress, GlobalTLSAddress, FrameIndex,
JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
- // The address of the GOT
+ /// The address of the GOT
GLOBAL_OFFSET_TABLE,
- // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
- // llvm.returnaddress on the DAG. These nodes take one operand, the index
- // of the frame or return address to return. An index of zero corresponds
- // to the current function's frame or return address, an index of one to the
- // parent's frame or return address, and so on.
+ /// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+ /// llvm.returnaddress on the DAG. These nodes take one operand, the index
+ /// of the frame or return address to return. An index of zero corresponds
+ /// to the current function's frame or return address, an index of one to
+ /// the parent's frame or return address, and so on.
FRAMEADDR, RETURNADDR,
- // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
- // first (possible) on-stack argument. This is needed for correct stack
- // adjustment during unwind.
+ /// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+ /// first (possible) on-stack argument. This is needed for correct stack
+ /// adjustment during unwind.
FRAME_TO_ARGS_OFFSET,
- // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
- // address of the exception block on entry to an landing pad block.
+ /// RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
+ /// address of the exception block on entry to an landing pad block.
EXCEPTIONADDR,
- // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
- // address of the Language Specific Data Area for the enclosing function.
+ /// RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
+ /// address of the Language Specific Data Area for the enclosing function.
LSDAADDR,
- // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
- // the selection index of the exception thrown.
+ /// RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node
+ /// represents the selection index of the exception thrown.
EHSELECTION,
- // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
- // 'eh_return' gcc dwarf builtin, which is used to return from
- // exception. The general meaning is: adjust stack by OFFSET and pass
- // execution to HANDLER. Many platform-related details also :)
+ /// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+ /// 'eh_return' gcc dwarf builtin, which is used to return from
+ /// exception. The general meaning is: adjust stack by OFFSET and pass
+ /// execution to HANDLER. Many platform-related details also :)
EH_RETURN,
- // RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
- // This corresponds to the eh.sjlj.setjmp intrinsic.
- // It takes an input chain and a pointer to the jump buffer as inputs
- // and returns an outchain.
+ /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
+ /// This corresponds to the eh.sjlj.setjmp intrinsic.
+ /// It takes an input chain and a pointer to the jump buffer as inputs
+ /// and returns an outchain.
EH_SJLJ_SETJMP,
- // OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
- // This corresponds to the eh.sjlj.longjmp intrinsic.
- // It takes an input chain and a pointer to the jump buffer as inputs
- // and returns an outchain.
+ /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
+ /// This corresponds to the eh.sjlj.longjmp intrinsic.
+ /// It takes an input chain and a pointer to the jump buffer as inputs
+ /// and returns an outchain.
EH_SJLJ_LONGJMP,
- // TargetConstant* - Like Constant*, but the DAG does not do any folding,
- // simplification, or lowering of the constant. They are used for constants
- // which are known to fit in the immediate fields of their users, or for
- // carrying magic numbers which are not values which need to be materialized
- // in registers.
+ /// TargetConstant* - Like Constant*, but the DAG does not do any folding,
+ /// simplification, or lowering of the constant. They are used for constants
+ /// which are known to fit in the immediate fields of their users, or for
+ /// carrying magic numbers which are not values which need to be
+ /// materialized in registers.
TargetConstant,
TargetConstantFP,
- // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
- // anything else with this node, and this is valid in the target-specific
- // dag, turning into a GlobalAddress operand.
+ /// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+ /// anything else with this node, and this is valid in the target-specific
+ /// dag, turning into a GlobalAddress operand.
TargetGlobalAddress,
TargetGlobalTLSAddress,
TargetFrameIndex,
@@ -126,6 +126,11 @@ namespace ISD {
TargetExternalSymbol,
TargetBlockAddress,
+ /// TargetIndex - Like a constant pool entry, but with completely
+ /// target-dependent semantics. Holds target flags, a 32-bit index, and a
+ /// 64-bit index. Targets can use this however they like.
+ TargetIndex,
+
/// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
/// This node represents a target intrinsic function with no side effects.
/// The first operand is the ID number of the intrinsic from the
@@ -148,93 +153,94 @@ namespace ISD {
/// namespace. The operands to the intrinsic follow.
INTRINSIC_VOID,
- // CopyToReg - This node has three operands: a chain, a register number to
- // set to this value, and a value.
+ /// CopyToReg - This node has three operands: a chain, a register number to
+ /// set to this value, and a value.
CopyToReg,
- // CopyFromReg - This node indicates that the input value is a virtual or
- // physical register that is defined outside of the scope of this
- // SelectionDAG. The register is available from the RegisterSDNode object.
+ /// CopyFromReg - This node indicates that the input value is a virtual or
+ /// physical register that is defined outside of the scope of this
+ /// SelectionDAG. The register is available from the RegisterSDNode object.
CopyFromReg,
- // UNDEF - An undefined node
+ /// UNDEF - An undefined node.
UNDEF,
- // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
- // a Constant, which is required to be operand #1) half of the integer or
- // float value specified as operand #0. This is only for use before
- // legalization, for values that will be broken into multiple registers.
+ /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
+ /// a Constant, which is required to be operand #1) half of the integer or
+ /// float value specified as operand #0. This is only for use before
+ /// legalization, for values that will be broken into multiple registers.
EXTRACT_ELEMENT,
- // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
- // two values of the same integer value type, this produces a value twice as
- // big. Like EXTRACT_ELEMENT, this can only be used before legalization.
+ /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
+ /// Given two values of the same integer value type, this produces a value
+ /// twice as big. Like EXTRACT_ELEMENT, this can only be used before
+ /// legalization.
BUILD_PAIR,
- // MERGE_VALUES - This node takes multiple discrete operands and returns
- // them all as its individual results. This nodes has exactly the same
- // number of inputs and outputs. This node is useful for some pieces of the
- // code generator that want to think about a single node with multiple
- // results, not multiple nodes.
+ /// MERGE_VALUES - This node takes multiple discrete operands and returns
+ /// them all as its individual results. This nodes has exactly the same
+ /// number of inputs and outputs. This node is useful for some pieces of the
+ /// code generator that want to think about a single node with multiple
+ /// results, not multiple nodes.
MERGE_VALUES,
- // Simple integer binary arithmetic operators.
+ /// Simple integer binary arithmetic operators.
ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
- // SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
- // a signed/unsigned value of type i[2*N], and return the full value as
- // two results, each of type iN.
+ /// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
+ /// a signed/unsigned value of type i[2*N], and return the full value as
+ /// two results, each of type iN.
SMUL_LOHI, UMUL_LOHI,
- // SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
- // remainder result.
+ /// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
+ /// remainder result.
SDIVREM, UDIVREM,
- // CARRY_FALSE - This node is used when folding other nodes,
- // like ADDC/SUBC, which indicate the carry result is always false.
+ /// CARRY_FALSE - This node is used when folding other nodes,
+ /// like ADDC/SUBC, which indicate the carry result is always false.
CARRY_FALSE,
- // Carry-setting nodes for multiple precision addition and subtraction.
- // These nodes take two operands of the same value type, and produce two
- // results. The first result is the normal add or sub result, the second
- // result is the carry flag result.
+ /// Carry-setting nodes for multiple precision addition and subtraction.
+ /// These nodes take two operands of the same value type, and produce two
+ /// results. The first result is the normal add or sub result, the second
+ /// result is the carry flag result.
ADDC, SUBC,
- // Carry-using nodes for multiple precision addition and subtraction. These
- // nodes take three operands: The first two are the normal lhs and rhs to
- // the add or sub, and the third is the input carry flag. These nodes
- // produce two results; the normal result of the add or sub, and the output
- // carry flag. These nodes both read and write a carry flag to allow them
- // to them to be chained together for add and sub of arbitrarily large
- // values.
+ /// Carry-using nodes for multiple precision addition and subtraction. These
+ /// nodes take three operands: The first two are the normal lhs and rhs to
+ /// the add or sub, and the third is the input carry flag. These nodes
+ /// produce two results; the normal result of the add or sub, and the output
+ /// carry flag. These nodes both read and write a carry flag to allow them
+ /// to them to be chained together for add and sub of arbitrarily large
+ /// values.
ADDE, SUBE,
- // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
- // These nodes take two operands: the normal LHS and RHS to the add. They
- // produce two results: the normal result of the add, and a boolean that
- // indicates if an overflow occurred (*not* a flag, because it may be stored
- // to memory, etc.). If the type of the boolean is not i1 then the high
- // bits conform to getBooleanContents.
- // These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
+ /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
+ /// These nodes take two operands: the normal LHS and RHS to the add. They
+ /// produce two results: the normal result of the add, and a boolean that
+ /// indicates if an overflow occurred (*not* a flag, because it may be store
+ /// to memory, etc.). If the type of the boolean is not i1 then the high
+ /// bits conform to getBooleanContents.
+ /// These nodes are generated from llvm.[su]add.with.overflow intrinsics.
SADDO, UADDO,
- // Same for subtraction
+ /// Same for subtraction.
SSUBO, USUBO,
- // Same for multiplication
+ /// Same for multiplication.
SMULO, UMULO,
- // Simple binary floating point operators.
+ /// Simple binary floating point operators.
FADD, FSUB, FMUL, FMA, FDIV, FREM,
- // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
- // DAG node does not require that X and Y have the same type, just that they
- // are both floating point. X and the result must have the same type.
- // FCOPYSIGN(f32, f64) is allowed.
+ /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ /// DAG node does not require that X and Y have the same type, just that the
+ /// are both floating point. X and the result must have the same type.
+ /// FCOPYSIGN(f32, f64) is allowed.
FCOPYSIGN,
- // INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
- // value as an integer 0/1 value.
+ /// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
+ /// value as an integer 0/1 value.
FGETSIGN,
/// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
@@ -292,13 +298,14 @@ namespace ISD {
/// than the vector element type, and is implicitly truncated to it.
SCALAR_TO_VECTOR,
- // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
- // an unsigned/signed value of type i[2*N], then return the top part.
+ /// MULHU/MULHS - Multiply high - Multiply two integers of type iN,
+ /// producing an unsigned/signed value of type i[2*N], then return the top
+ /// part.
MULHU, MULHS,
/// Bitwise operators - logical and, logical or, logical xor.
AND, OR, XOR,
-
+
/// Shift and rotation operations. After legalization, the type of the
/// shift amount is known to be TLI.getShiftAmountTy(). Before legalization
/// the shift amount can be any type, but care must be taken to ensure it is
@@ -306,7 +313,6 @@ namespace ISD {
/// legalization, types like i1024 can occur and i8 doesn't have enough bits
/// to represent the shift amount. By convention, DAGCombine and
/// SelectionDAGBuilder forces these shift amounts to i32 for simplicity.
- ///
SHL, SRA, SRL, ROTL, ROTR,
/// Byte Swap and Counting operators.
@@ -315,67 +321,67 @@ namespace ISD {
/// Bit counting operators with an undefined result for zero inputs.
CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF,
- // Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
- // i1 then the high bits must conform to getBooleanContents.
+ /// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
+ /// i1 then the high bits must conform to getBooleanContents.
SELECT,
- // Select with a vector condition (op #0) and two vector operands (ops #1
- // and #2), returning a vector result. All vectors have the same length.
- // Much like the scalar select and setcc, each bit in the condition selects
- // whether the corresponding result element is taken from op #1 or op #2.
- // At first, the VSELECT condition is of vXi1 type. Later, targets may change
- // the condition type in order to match the VSELECT node using a a pattern.
- // The condition follows the BooleanContent format of the target.
+ /// Select with a vector condition (op #0) and two vector operands (ops #1
+ /// and #2), returning a vector result. All vectors have the same length.
+ /// Much like the scalar select and setcc, each bit in the condition selects
+ /// whether the corresponding result element is taken from op #1 or op #2.
+ /// At first, the VSELECT condition is of vXi1 type. Later, targets may
+ /// change the condition type in order to match the VSELECT node using a
+ /// pattern. The condition follows the BooleanContent format of the target.
VSELECT,
- // Select with condition operator - This selects between a true value and
- // a false value (ops #2 and #3) based on the boolean result of comparing
- // the lhs and rhs (ops #0 and #1) of a conditional expression with the
- // condition code in op #4, a CondCodeSDNode.
+ /// Select with condition operator - This selects between a true value and
+ /// a false value (ops #2 and #3) based on the boolean result of comparing
+ /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
+ /// condition code in op #4, a CondCodeSDNode.
SELECT_CC,
- // SetCC operator - This evaluates to a true value iff the condition is
- // true. If the result value type is not i1 then the high bits conform
- // to getBooleanContents. The operands to this are the left and right
- // operands to compare (ops #0, and #1) and the condition code to compare
- // them with (op #2) as a CondCodeSDNode. If the operands are vector types
- // then the result type must also be a vector type.
+ /// SetCC operator - This evaluates to a true value iff the condition is
+ /// true. If the result value type is not i1 then the high bits conform
+ /// to getBooleanContents. The operands to this are the left and right
+ /// operands to compare (ops #0, and #1) and the condition code to compare
+ /// them with (op #2) as a CondCodeSDNode. If the operands are vector types
+ /// then the result type must also be a vector type.
SETCC,
- // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
- // integer shift operations, just like ADD/SUB_PARTS. The operation
- // ordering is:
- // [Lo,Hi] = op [LoLHS,HiLHS], Amt
+ /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+ /// integer shift operations, just like ADD/SUB_PARTS. The operation
+ /// ordering is:
+ /// [Lo,Hi] = op [LoLHS,HiLHS], Amt
SHL_PARTS, SRA_PARTS, SRL_PARTS,
- // Conversion operators. These are all single input single output
- // operations. For all of these, the result type must be strictly
- // wider or narrower (depending on the operation) than the source
- // type.
+ /// Conversion operators. These are all single input single output
+ /// operations. For all of these, the result type must be strictly
+ /// wider or narrower (depending on the operation) than the source
+ /// type.
- // SIGN_EXTEND - Used for integer types, replicating the sign bit
- // into new bits.
+ /// SIGN_EXTEND - Used for integer types, replicating the sign bit
+ /// into new bits.
SIGN_EXTEND,
- // ZERO_EXTEND - Used for integer types, zeroing the new bits.
+ /// ZERO_EXTEND - Used for integer types, zeroing the new bits.
ZERO_EXTEND,
- // ANY_EXTEND - Used for integer types. The high bits are undefined.
+ /// ANY_EXTEND - Used for integer types. The high bits are undefined.
ANY_EXTEND,
- // TRUNCATE - Completely drop the high bits.
+ /// TRUNCATE - Completely drop the high bits.
TRUNCATE,
- // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
- // depends on the first letter) to floating point.
+ /// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+ /// depends on the first letter) to floating point.
SINT_TO_FP,
UINT_TO_FP,
- // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
- // sign extend a small value in a large integer register (e.g. sign
- // extending the low 8 bits of a 32-bit register to fill the top 24 bits
- // with the 7th bit). The size of the smaller type is indicated by the 1th
- // operand, a ValueType node.
+ /// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+ /// sign extend a small value in a large integer register (e.g. sign
+ /// extending the low 8 bits of a 32-bit register to fill the top 24 bits
+ /// with the 7th bit). The size of the smaller type is indicated by the 1th
+ /// operand, a ValueType node.
SIGN_EXTEND_INREG,
/// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
@@ -396,12 +402,12 @@ namespace ISD {
/// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
FP_ROUND,
- // FLT_ROUNDS_ - Returns current rounding mode:
- // -1 Undefined
- // 0 Round to 0
- // 1 Round to nearest
- // 2 Round to +inf
- // 3 Round to -inf
+ /// FLT_ROUNDS_ - Returns current rounding mode:
+ /// -1 Undefined
+ /// 0 Round to 0
+ /// 1 Round to nearest
+ /// 2 Round to +inf
+ /// 3 Round to -inf
FLT_ROUNDS_,
/// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and
@@ -414,208 +420,211 @@ namespace ISD {
/// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
FP_EXTEND,
- // BITCAST - This operator converts between integer, vector and FP
- // values, as if the value was stored to memory with one type and loaded
- // from the same address with the other type (or equivalently for vector
- // format conversions, etc). The source and result are required to have
- // the same bit size (e.g. f32 <-> i32). This can also be used for
- // int-to-int or fp-to-fp conversions, but that is a noop, deleted by
- // getNode().
+ /// BITCAST - This operator converts between integer, vector and FP
+ /// values, as if the value was stored to memory with one type and loaded
+ /// from the same address with the other type (or equivalently for vector
+ /// format conversions, etc). The source and result are required to have
+ /// the same bit size (e.g. f32 <-> i32). This can also be used for
+ /// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
+ /// getNode().
BITCAST,
- // CONVERT_RNDSAT - This operator is used to support various conversions
- // between various types (float, signed, unsigned and vectors of those
- // types) with rounding and saturation. NOTE: Avoid using this operator as
- // most target don't support it and the operator might be removed in the
- // future. It takes the following arguments:
- // 0) value
- // 1) dest type (type to convert to)
- // 2) src type (type to convert from)
- // 3) rounding imm
- // 4) saturation imm
- // 5) ISD::CvtCode indicating the type of conversion to do
+ /// CONVERT_RNDSAT - This operator is used to support various conversions
+ /// between various types (float, signed, unsigned and vectors of those
+ /// types) with rounding and saturation. NOTE: Avoid using this operator as
+ /// most target don't support it and the operator might be removed in the
+ /// future. It takes the following arguments:
+ /// 0) value
+ /// 1) dest type (type to convert to)
+ /// 2) src type (type to convert from)
+ /// 3) rounding imm
+ /// 4) saturation imm
+ /// 5) ISD::CvtCode indicating the type of conversion to do
CONVERT_RNDSAT,
- // FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
- // promotions and truncation for half-precision (16 bit) floating
- // numbers. We need special nodes since FP16 is a storage-only type with
- // special semantics of operations.
+ /// FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
+ /// promotions and truncation for half-precision (16 bit) floating
+ /// numbers. We need special nodes since FP16 is a storage-only type with
+ /// special semantics of operations.
FP16_TO_FP32, FP32_TO_FP16,
- // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
- // FLOG, FLOG2, FLOG10, FEXP, FEXP2,
- // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
- // point operations. These are inspired by libm.
+ /// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
+ /// FLOG, FLOG2, FLOG10, FEXP, FEXP2,
+ /// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary
+ /// floating point operations. These are inspired by libm.
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
- // LOAD and STORE have token chains as their first operand, then the same
- // operands as an LLVM load/store instruction, then an offset node that
- // is added / subtracted from the base pointer to form the address (for
- // indexed memory ops).
+ /// LOAD and STORE have token chains as their first operand, then the same
+ /// operands as an LLVM load/store instruction, then an offset node that
+ /// is added / subtracted from the base pointer to form the address (for
+ /// indexed memory ops).
LOAD, STORE,
- // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
- // 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 chain,
- // the second is the number of bytes to allocate, and the third is the
- // alignment boundary. The size is guaranteed to be a multiple of the stack
- // alignment, and the alignment is guaranteed to be bigger than the stack
- // alignment (if required) or 0 to get standard stack alignment.
+ /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+ /// 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 chain,
+ /// the second is the number of bytes to allocate, and the third is the
+ /// alignment boundary. The size is guaranteed to be a multiple of the
+ /// stack alignment, and the alignment is guaranteed to be bigger than the
+ /// stack alignment (if required) or 0 to get standard stack alignment.
DYNAMIC_STACKALLOC,
- // Control flow instructions. These all have token chains.
+ /// Control flow instructions. These all have token chains.
- // BR - Unconditional branch. The first operand is the chain
- // operand, the second is the MBB to branch to.
+ /// BR - Unconditional branch. The first operand is the chain
+ /// operand, the second is the MBB to branch to.
BR,
- // BRIND - Indirect branch. The first operand is the chain, the second
- // is the value to branch to, which must be of the same type as the target's
- // pointer type.
+ /// BRIND - Indirect branch. The first operand is the chain, the second
+ /// is the value to branch to, which must be of the same type as the
+ /// target's pointer type.
BRIND,
- // BR_JT - Jumptable branch. The first operand is the chain, the second
- // is the jumptable index, the last one is the jumptable entry index.
+ /// BR_JT - Jumptable branch. The first operand is the chain, the second
+ /// is the jumptable index, the last one is the jumptable entry index.
BR_JT,
- // BRCOND - Conditional branch. The first operand is the chain, the
- // second is the condition, the third is the block to branch to if the
- // condition is true. If the type of the condition is not i1, then the
- // high bits must conform to getBooleanContents.
+ /// BRCOND - Conditional branch. The first operand is the chain, the
+ /// second is the condition, the third is the block to branch to if the
+ /// condition is true. If the type of the condition is not i1, then the
+ /// high bits must conform to getBooleanContents.
BRCOND,
- // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
- // that the condition is represented as condition code, and two nodes to
- // compare, rather than as a combined SetCC node. The operands in order are
- // chain, cc, lhs, rhs, block to branch to if condition is true.
+ /// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
+ /// that the condition is represented as condition code, and two nodes to
+ /// compare, rather than as a combined SetCC node. The operands in order
+ /// are chain, cc, lhs, rhs, block to branch to if condition is true.
BR_CC,
- // INLINEASM - Represents an inline asm block. This node always has two
- // return values: a chain and a flag result. The inputs are as follows:
- // Operand #0 : Input chain.
- // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
- // Operand #2 : a MDNodeSDNode with the !srcloc metadata.
- // Operand #3 : HasSideEffect, IsAlignStack bits.
- // After this, it is followed by a list of operands with this format:
- // ConstantSDNode: Flags that encode whether it is a mem or not, the
- // of operands that follow, etc. See InlineAsm.h.
- // ... however many operands ...
- // Operand #last: Optional, an incoming flag.
- //
- // The variable width operands are required to represent target addressing
- // modes as a single "operand", even though they may have multiple
- // SDOperands.
+ /// INLINEASM - Represents an inline asm block. This node always has two
+ /// return values: a chain and a flag result. The inputs are as follows:
+ /// Operand #0 : Input chain.
+ /// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ /// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
+ /// Operand #3 : HasSideEffect, IsAlignStack bits.
+ /// After this, it is followed by a list of operands with this format:
+ /// ConstantSDNode: Flags that encode whether it is a mem or not, the
+ /// of operands that follow, etc. See InlineAsm.h.
+ /// ... however many operands ...
+ /// Operand #last: Optional, an incoming flag.
+ ///
+ /// The variable width operands are required to represent target addressing
+ /// modes as a single "operand", even though they may have multiple
+ /// SDOperands.
INLINEASM,
- // EH_LABEL - Represents a label in mid basic block used to track
- // locations needed for debug and exception handling tables. These nodes
- // take a chain as input and return a chain.
+ /// EH_LABEL - Represents a label in mid basic block used to track
+ /// locations needed for debug and exception handling tables. These nodes
+ /// take a chain as input and return a chain.
EH_LABEL,
- // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
- // value, the same type as the pointer type for the system, and an output
- // chain.
+ /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ /// value, the same type as the pointer type for the system, and an output
+ /// chain.
STACKSAVE,
- // STACKRESTORE has two operands, an input chain and a pointer to restore to
- // it returns an output chain.
+ /// STACKRESTORE has two operands, an input chain and a pointer to restore
+ /// to it returns an output chain.
STACKRESTORE,
- // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
- // a call sequence, and carry arbitrary information that target might want
- // to know. The first operand is a chain, the rest are specified by the
- // target and not touched by the DAG optimizers.
- // CALLSEQ_START..CALLSEQ_END pairs may not be nested.
+ /// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end
+ /// of a call sequence, and carry arbitrary information that target might
+ /// want to know. The first operand is a chain, the rest are specified by
+ /// the target and not touched by the DAG optimizers.
+ /// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
CALLSEQ_START, // Beginning of a call sequence
CALLSEQ_END, // End of a call sequence
- // VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
- // and the alignment. It returns a pair of values: the vaarg value and a
- // new chain.
+ /// VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
+ /// and the alignment. It returns a pair of values: the vaarg value and a
+ /// new chain.
VAARG,
- // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
- // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
- // source.
+ /// VACOPY - VACOPY has 5 operands: an input chain, a destination pointer,
+ /// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ /// source.
VACOPY,
- // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
- // pointer, and a SRCVALUE.
+ /// VAEND, VASTART - VAEND and VASTART have three operands: an input chain,
+ /// pointer, and a SRCVALUE.
VAEND, VASTART,
- // SRCVALUE - This is a node type that holds a Value* that is used to
- // make reference to a value in the LLVM IR.
+ /// SRCVALUE - This is a node type that holds a Value* that is used to
+ /// make reference to a value in the LLVM IR.
SRCVALUE,
- // MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
- // reference metadata in the IR.
+ /// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
+ /// reference metadata in the IR.
MDNODE_SDNODE,
- // PCMARKER - This corresponds to the pcmarker intrinsic.
+ /// PCMARKER - This corresponds to the pcmarker intrinsic.
PCMARKER,
- // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
- // The only operand is a chain and a value and a chain are produced. The
- // value is the contents of the architecture specific cycle counter like
- // register (or other high accuracy low latency clock source)
+ /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+ /// The only operand is a chain and a value and a chain are produced. The
+ /// value is the contents of the architecture specific cycle counter like
+ /// register (or other high accuracy low latency clock source)
READCYCLECOUNTER,
- // HANDLENODE node - Used as a handle for various purposes.
+ /// HANDLENODE node - Used as a handle for various purposes.
HANDLENODE,
- // INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
- // takes as input a token chain, the pointer to the trampoline, the pointer
- // to the nested function, the pointer to pass for the 'nest' parameter, a
- // SRCVALUE for the trampoline and another for the nested function (allowing
- // targets to access the original Function*). It produces a token chain as
- // output.
+ /// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
+ /// takes as input a token chain, the pointer to the trampoline, the pointer
+ /// to the nested function, the pointer to pass for the 'nest' parameter, a
+ /// SRCVALUE for the trampoline and another for the nested function
+ /// (allowing targets to access the original Function*).
+ /// It produces a token chain as output.
INIT_TRAMPOLINE,
- // ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
- // It takes a pointer to the trampoline and produces a (possibly) new
- // pointer to the same trampoline with platform-specific adjustments
- // applied. The pointer it returns points to an executable block of code.
+ /// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
+ /// It takes a pointer to the trampoline and produces a (possibly) new
+ /// pointer to the same trampoline with platform-specific adjustments
+ /// applied. The pointer it returns points to an executable block of code.
ADJUST_TRAMPOLINE,
- // TRAP - Trapping instruction
+ /// TRAP - Trapping instruction
TRAP,
- // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
- // their first operand. The other operands are the address to prefetch,
- // read / write specifier, locality specifier and instruction / data cache
- // specifier.
+ /// DEBUGTRAP - Trap intended to get the attention of a debugger.
+ DEBUGTRAP,
+
+ /// PREFETCH - This corresponds to a prefetch intrinsic. The first operand
+ /// is the chain. The other operands are the address to prefetch,
+ /// read / write specifier, locality specifier and instruction / data cache
+ /// specifier.
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 memory
- // and produces an output chain.
+ /// 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 memory
+ /// and produces an output chain.
MEMBARRIER,
- // OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
- // This corresponds to the fence instruction. It takes an input chain, and
- // two integer constants: an AtomicOrdering and a SynchronizationScope.
+ /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
+ /// This corresponds to the fence instruction. It takes an input chain, and
+ /// two integer constants: an AtomicOrdering and a SynchronizationScope.
ATOMIC_FENCE,
- // Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
- // This corresponds to "load atomic" instruction.
+ /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
+ /// This corresponds to "load atomic" instruction.
ATOMIC_LOAD,
- // OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val)
- // This corresponds to "store atomic" instruction.
+ /// OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val)
+ /// This corresponds to "store atomic" instruction.
ATOMIC_STORE,
- // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
- // This corresponds to the cmpxchg instruction.
+ /// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
+ /// This corresponds to the cmpxchg instruction.
ATOMIC_CMP_SWAP,
- // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
- // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
- // These correspond to the atomicrmw instruction.
+ /// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
+ /// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
+ /// These correspond to the atomicrmw instruction.
ATOMIC_SWAP,
ATOMIC_LOAD_ADD,
ATOMIC_LOAD_SUB,
@@ -790,16 +799,16 @@ namespace ISD {
/// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
/// supports.
enum CvtCode {
- CVT_FF, // Float from Float
- CVT_FS, // Float from Signed
- CVT_FU, // Float from Unsigned
- CVT_SF, // Signed from Float
- CVT_UF, // Unsigned from Float
- CVT_SS, // Signed from Signed
- CVT_SU, // Signed from Unsigned
- CVT_US, // Unsigned from Signed
- CVT_UU, // Unsigned from Unsigned
- CVT_INVALID // Marker - Invalid opcode
+ CVT_FF, /// Float from Float
+ CVT_FS, /// Float from Signed
+ CVT_FU, /// Float from Unsigned
+ CVT_SF, /// Signed from Float
+ CVT_UF, /// Unsigned from Float
+ CVT_SS, /// Signed from Signed
+ CVT_SU, /// Signed from Unsigned
+ CVT_US, /// Unsigned from Signed
+ CVT_UU, /// Unsigned from Unsigned
+ CVT_INVALID /// Marker - Invalid opcode
};
} // end llvm::ISD namespace
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index eb01f66c3129..8414c64544e5 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -158,7 +158,10 @@ class LexicalScope {
public:
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
- LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) {
+ LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) {
+#ifndef NDEBUG
+ IndentLevel = 0;
+#endif
if (Parent)
Parent->addChild(this);
}
@@ -241,7 +244,9 @@ private:
const MachineInstr *FirstInsn; // First instruction of this scope.
unsigned DFSIn, DFSOut; // In & Out Depth use to determine
// scope nesting.
+#ifndef NDEBUG
mutable unsigned IndentLevel; // Private state for dump()
+#endif
};
} // end llvm namespace
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index a6008ab33761..a3ce47c02a1a 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -40,15 +40,6 @@ namespace llvm {
/// definition and use points.
///
class VNInfo {
- private:
- enum {
- HAS_PHI_KILL = 1,
- IS_PHI_DEF = 1 << 1,
- IS_UNUSED = 1 << 2
- };
-
- unsigned char flags;
-
public:
typedef BumpPtrAllocator Allocator;
@@ -60,60 +51,30 @@ namespace llvm {
/// VNInfo constructor.
VNInfo(unsigned i, SlotIndex d)
- : flags(0), id(i), def(d)
+ : id(i), def(d)
{ }
/// VNInfo construtor, copies values from orig, except for the value number.
VNInfo(unsigned i, const VNInfo &orig)
- : flags(orig.flags), id(i), def(orig.def)
+ : id(i), def(orig.def)
{ }
/// Copy from the parameter into this VNInfo.
void copyFrom(VNInfo &src) {
- flags = src.flags;
def = src.def;
}
- /// Used for copying value number info.
- unsigned getFlags() const { return flags; }
- void setFlags(unsigned flags) { this->flags = flags; }
-
- /// Merge flags from another VNInfo
- void mergeFlags(const VNInfo *VNI) {
- flags = (flags | VNI->flags) & ~IS_UNUSED;
- }
-
- /// Returns true if one or more kills are PHI nodes.
- /// Obsolete, do not use!
- bool hasPHIKill() const { return flags & HAS_PHI_KILL; }
- /// Set the PHI kill flag on this value.
- void setHasPHIKill(bool hasKill) {
- if (hasKill)
- flags |= HAS_PHI_KILL;
- else
- flags &= ~HAS_PHI_KILL;
- }
-
/// Returns true if this value is defined by a PHI instruction (or was,
/// PHI instrucions may have been eliminated).
- bool isPHIDef() const { return flags & IS_PHI_DEF; }
- /// Set the "phi def" flag on this value.
- void setIsPHIDef(bool phiDef) {
- if (phiDef)
- flags |= IS_PHI_DEF;
- else
- flags &= ~IS_PHI_DEF;
- }
+ /// PHI-defs begin at a block boundary, all other defs begin at register or
+ /// EC slots.
+ bool isPHIDef() const { return def.isBlock(); }
/// Returns true if this value is unused.
- bool isUnused() const { return flags & IS_UNUSED; }
- /// Set the "is unused" flag on this value.
- void setIsUnused(bool unused) {
- if (unused)
- flags |= IS_UNUSED;
- else
- flags &= ~IS_UNUSED;
- }
+ bool isUnused() const { return !def.isValid(); }
+
+ /// Mark this value as unused.
+ void markUnused() { def = SlotIndex(); }
};
/// LiveRange structure - This represents a simple register range in the
@@ -274,6 +235,11 @@ namespace llvm {
return VNI;
}
+ /// createDeadDef - Make sure the interval has a value defined at Def.
+ /// If one already exists, return it. Otherwise allocate a new value and
+ /// add liveness for a dead def.
+ VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator);
+
/// Create a copy of the given value. The new value will be identical except
/// for the Value number.
VNInfo *createValueCopy(const VNInfo *orig,
@@ -288,17 +254,6 @@ namespace llvm {
/// unused values.
void RenumberValues(LiveIntervals &lis);
- /// isOnlyLROfValNo - Return true if the specified live range is the only
- /// one defined by the its val#.
- bool isOnlyLROfValNo(const LiveRange *LR) {
- for (const_iterator I = begin(), E = end(); I != E; ++I) {
- const LiveRange *Tmp = I;
- if (Tmp != LR && Tmp->valno == LR->valno)
- return false;
- }
- return true;
- }
-
/// MergeValueNumberInto - This method is called when two value nubmers
/// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can
@@ -377,14 +332,6 @@ namespace llvm {
return I == end() ? 0 : &*I;
}
- const LiveRange *getLiveRangeBefore(SlotIndex Idx) const {
- return getLiveRangeContaining(Idx.getPrevSlot());
- }
-
- LiveRange *getLiveRangeBefore(SlotIndex Idx) {
- return getLiveRangeContaining(Idx.getPrevSlot());
- }
-
/// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
VNInfo *getVNInfoAt(SlotIndex Idx) const {
const_iterator I = FindLiveRangeContaining(Idx);
@@ -411,11 +358,6 @@ namespace llvm {
return I != end() && I->start <= Idx ? I : end();
}
- /// findDefinedVNInfo - Find the by the specified
- /// index (register interval) or defined
- VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const;
-
-
/// overlaps - Return true if the intersection of the two live intervals is
/// not empty.
bool overlaps(const LiveInterval& other) const {
@@ -498,10 +440,6 @@ namespace llvm {
weight = HUGE_VALF;
}
- /// ComputeJoinedWeight - Set the weight of a live interval after
- /// Other has been merged into it.
- void ComputeJoinedWeight(const LiveInterval &Other);
-
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
const SlotIndex &otherIndex = other.beginIndex();
@@ -509,15 +447,27 @@ namespace llvm {
(thisIndex == otherIndex && reg < other.reg));
}
- void print(raw_ostream &OS, const TargetRegisterInfo *TRI = 0) const;
+ void print(raw_ostream &OS) const;
void dump() const;
+ /// \brief Walk the interval and assert if any invariants fail to hold.
+ ///
+ /// Note that this is a no-op when asserts are disabled.
+#ifdef NDEBUG
+ void verify() const {}
+#else
+ void verify() const;
+#endif
+
private:
Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
void markValNoForDeletion(VNInfo *V);
+ void mergeIntervalRanges(const LiveInterval &RHS,
+ VNInfo *LHSValNo = 0,
+ const VNInfo *RHSValNo = 0);
LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
@@ -528,6 +478,91 @@ namespace llvm {
return OS;
}
+ /// LiveRangeQuery - Query information about a live range around a given
+ /// instruction. This class hides the implementation details of live ranges,
+ /// and it should be used as the primary interface for examining live ranges
+ /// around instructions.
+ ///
+ class LiveRangeQuery {
+ VNInfo *EarlyVal;
+ VNInfo *LateVal;
+ SlotIndex EndPoint;
+ bool Kill;
+
+ public:
+ /// Create a LiveRangeQuery for the given live range and instruction index.
+ /// The sub-instruction slot of Idx doesn't matter, only the instruction it
+ /// refers to is considered.
+ LiveRangeQuery(const LiveInterval &LI, SlotIndex Idx)
+ : EarlyVal(0), LateVal(0), Kill(false) {
+ // Find the segment that enters the instruction.
+ LiveInterval::const_iterator I = LI.find(Idx.getBaseIndex());
+ LiveInterval::const_iterator E = LI.end();
+ if (I == E)
+ return;
+ // Is this an instruction live-in segment?
+ if (SlotIndex::isEarlierInstr(I->start, Idx)) {
+ EarlyVal = I->valno;
+ EndPoint = I->end;
+ // Move to the potentially live-out segment.
+ if (SlotIndex::isSameInstr(Idx, I->end)) {
+ Kill = true;
+ if (++I == E)
+ return;
+ }
+ }
+ // I now points to the segment that may be live-through, or defined by
+ // this instr. Ignore segments starting after the current instr.
+ if (SlotIndex::isEarlierInstr(Idx, I->start))
+ return;
+ LateVal = I->valno;
+ EndPoint = I->end;
+ }
+
+ /// Return the value that is live-in to the instruction. This is the value
+ /// that will be read by the instruction's use operands. Return NULL if no
+ /// value is live-in.
+ VNInfo *valueIn() const {
+ return EarlyVal;
+ }
+
+ /// Return true if the live-in value is killed by this instruction. This
+ /// means that either the live range ends at the instruction, or it changes
+ /// value.
+ bool isKill() const {
+ return Kill;
+ }
+
+ /// Return true if this instruction has a dead def.
+ bool isDeadDef() const {
+ return EndPoint.isDead();
+ }
+
+ /// Return the value leaving the instruction, if any. This can be a
+ /// live-through value, or a live def. A dead def returns NULL.
+ VNInfo *valueOut() const {
+ return isDeadDef() ? 0 : LateVal;
+ }
+
+ /// Return the value defined by this instruction, if any. This includes
+ /// dead defs, it is the value created by the instruction's def operands.
+ VNInfo *valueDefined() const {
+ return EarlyVal == LateVal ? 0 : LateVal;
+ }
+
+ /// Return the end point of the last live range segment to interact with
+ /// the instruction, if any.
+ ///
+ /// The end point is an invalid SlotIndex only if the live range doesn't
+ /// intersect the instruction at all.
+ ///
+ /// The end point may be at or past the end of the instruction's basic
+ /// block. That means the value was live out of the block.
+ SlotIndex endPoint() const {
+ return EndPoint;
+ }
+ };
+
/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
/// LiveInterval into equivalence clases of connected components. A
/// LiveInterval that has multiple connected components can be broken into
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 76201c96f915..da521dbc535f 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -20,12 +20,13 @@
#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
@@ -35,7 +36,9 @@
namespace llvm {
class AliasAnalysis;
+ class LiveRangeCalc;
class LiveVariables;
+ class MachineDominatorTree;
class MachineLoopInfo;
class TargetRegisterInfo;
class MachineRegisterInfo;
@@ -44,27 +47,29 @@ namespace llvm {
class VirtRegMap;
class LiveIntervals : public MachineFunctionPass {
- MachineFunction* mf_;
- MachineRegisterInfo* mri_;
- const TargetMachine* tm_;
- const TargetRegisterInfo* tri_;
- const TargetInstrInfo* tii_;
- AliasAnalysis *aa_;
- LiveVariables* lv_;
- SlotIndexes* indexes_;
+ MachineFunction* MF;
+ MachineRegisterInfo* MRI;
+ const TargetMachine* TM;
+ const TargetRegisterInfo* TRI;
+ const TargetInstrInfo* TII;
+ AliasAnalysis *AA;
+ LiveVariables* LV;
+ SlotIndexes* Indexes;
+ MachineDominatorTree *DomTree;
+ LiveRangeCalc *LRCalc;
/// Special pool allocator for VNInfo's (LiveInterval val#).
///
VNInfo::Allocator VNInfoAllocator;
- typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
- Reg2IntervalMap r2iMap_;
+ /// Live interval pointers for all the virtual registers.
+ IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
- /// allocatableRegs_ - A bit vector of allocatable registers.
- BitVector allocatableRegs_;
+ /// AllocatableRegs - A bit vector of allocatable registers.
+ BitVector AllocatableRegs;
- /// reservedRegs_ - A bit vector of reserved registers.
- BitVector reservedRegs_;
+ /// ReservedRegs - A bit vector of reserved registers.
+ BitVector ReservedRegs;
/// RegMaskSlots - Sorted list of instructions with register mask operands.
/// Always use the 'r' slot, RegMasks are normal clobbers, not early
@@ -92,83 +97,59 @@ namespace llvm {
/// block.
SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
+ /// RegUnitIntervals - Keep a live interval for each register unit as a way
+ /// of tracking fixed physreg interference.
+ SmallVector<LiveInterval*, 0> RegUnitIntervals;
+
public:
static char ID; // Pass identification, replacement for typeid
- LiveIntervals() : MachineFunctionPass(ID) {
- initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
- }
+ LiveIntervals();
+ virtual ~LiveIntervals();
// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
- typedef Reg2IntervalMap::iterator iterator;
- typedef Reg2IntervalMap::const_iterator const_iterator;
- const_iterator begin() const { return r2iMap_.begin(); }
- const_iterator end() const { return r2iMap_.end(); }
- iterator begin() { return r2iMap_.begin(); }
- iterator end() { return r2iMap_.end(); }
- unsigned getNumIntervals() const { return (unsigned)r2iMap_.size(); }
-
- LiveInterval &getInterval(unsigned reg) {
- Reg2IntervalMap::iterator I = r2iMap_.find(reg);
- assert(I != r2iMap_.end() && "Interval does not exist for register");
- return *I->second;
+ LiveInterval &getInterval(unsigned Reg) {
+ LiveInterval *LI = VirtRegIntervals[Reg];
+ assert(LI && "Interval does not exist for virtual register");
+ return *LI;
}
- const LiveInterval &getInterval(unsigned reg) const {
- Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
- assert(I != r2iMap_.end() && "Interval does not exist for register");
- return *I->second;
+ const LiveInterval &getInterval(unsigned Reg) const {
+ return const_cast<LiveIntervals*>(this)->getInterval(Reg);
}
- bool hasInterval(unsigned reg) const {
- return r2iMap_.count(reg);
+ bool hasInterval(unsigned Reg) const {
+ return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
}
/// isAllocatable - is the physical register reg allocatable in the current
/// function?
bool isAllocatable(unsigned reg) const {
- return allocatableRegs_.test(reg);
+ return AllocatableRegs.test(reg);
}
/// isReserved - is the physical register reg reserved in the current
/// function
bool isReserved(unsigned reg) const {
- return reservedRegs_.test(reg);
- }
-
- /// getScaledIntervalSize - get the size of an interval in "units,"
- /// where every function is composed of one thousand units. This
- /// measure scales properly with empty index slots in the function.
- double getScaledIntervalSize(LiveInterval& I) {
- return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
- }
-
- /// getFuncInstructionCount - Return the number of instructions in the
- /// current function.
- unsigned getFuncInstructionCount() {
- return indexes_->getFunctionSize();
+ return ReservedRegs.test(reg);
}
- /// getApproximateInstructionCount - computes an estimate of the number
- /// of instructions in a given LiveInterval.
- unsigned getApproximateInstructionCount(LiveInterval& I) {
- double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
- return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
+ // Interval creation.
+ LiveInterval &getOrCreateInterval(unsigned Reg) {
+ if (!hasInterval(Reg)) {
+ VirtRegIntervals.grow(Reg);
+ VirtRegIntervals[Reg] = createInterval(Reg);
+ }
+ return getInterval(Reg);
}
- // Interval creation
- LiveInterval &getOrCreateInterval(unsigned reg) {
- Reg2IntervalMap::iterator I = r2iMap_.find(reg);
- if (I == r2iMap_.end())
- I = r2iMap_.insert(std::make_pair(reg, createInterval(reg))).first;
- return *I->second;
+ // Interval removal.
+ void removeInterval(unsigned Reg) {
+ delete VirtRegIntervals[Reg];
+ VirtRegIntervals[Reg] = 0;
}
- /// dupInterval - Duplicate a live interval. The caller is responsible for
- /// managing the allocated memory.
- LiveInterval *dupInterval(LiveInterval *li);
-
/// addLiveRangeToEndOfBlock - Given a register and an instruction,
/// adds a live range from that instruction to the end of its MBB.
LiveRange addLiveRangeToEndOfBlock(unsigned reg,
@@ -184,42 +165,38 @@ namespace llvm {
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = 0);
- // Interval removal
-
- void removeInterval(unsigned Reg) {
- DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.find(Reg);
- delete I->second;
- r2iMap_.erase(I);
+ SlotIndexes *getSlotIndexes() const {
+ return Indexes;
}
- SlotIndexes *getSlotIndexes() const {
- return indexes_;
+ AliasAnalysis *getAliasAnalysis() const {
+ return AA;
}
/// isNotInMIMap - returns true if the specified machine instr has been
/// removed or was never entered in the map.
bool isNotInMIMap(const MachineInstr* Instr) const {
- return !indexes_->hasIndex(Instr);
+ return !Indexes->hasIndex(Instr);
}
/// Returns the base index of the given instruction.
SlotIndex getInstructionIndex(const MachineInstr *instr) const {
- return indexes_->getInstructionIndex(instr);
+ return Indexes->getInstructionIndex(instr);
}
/// Returns the instruction associated with the given index.
MachineInstr* getInstructionFromIndex(SlotIndex index) const {
- return indexes_->getInstructionFromIndex(index);
+ return Indexes->getInstructionFromIndex(index);
}
/// Return the first index in the given basic block.
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
- return indexes_->getMBBStartIdx(mbb);
+ return Indexes->getMBBStartIdx(mbb);
}
/// Return the last index in the given basic block.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
- return indexes_->getMBBEndIdx(mbb);
+ return Indexes->getMBBEndIdx(mbb);
}
bool isLiveInToMBB(const LiveInterval &li,
@@ -233,24 +210,24 @@ namespace llvm {
}
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
- return indexes_->getMBBFromIndex(index);
+ return Indexes->getMBBFromIndex(index);
}
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
- return indexes_->insertMachineInstrInMaps(MI);
+ return Indexes->insertMachineInstrInMaps(MI);
}
void RemoveMachineInstrFromMaps(MachineInstr *MI) {
- indexes_->removeMachineInstrFromMaps(MI);
+ Indexes->removeMachineInstrFromMaps(MI);
}
void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
- indexes_->replaceMachineInstrInMaps(MI, NewMI);
+ Indexes->replaceMachineInstrInMaps(MI, NewMI);
}
bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
- return indexes_->findLiveInMBBs(Start, End, MBBs);
+ return Indexes->findLiveInMBBs(Start, End, MBBs);
}
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
@@ -264,18 +241,15 @@ namespace llvm {
/// print - Implement the dump method.
virtual void print(raw_ostream &O, const Module* = 0) const;
- /// isReMaterializable - Returns true if every definition of MI of every
- /// val# of the specified interval is re-materializable. Also returns true
- /// by reference if all of the defs are load instructions.
- bool isReMaterializable(const LiveInterval &li,
- const SmallVectorImpl<LiveInterval*> *SpillIs,
- bool &isLoad);
-
/// intervalIsInOneMBB - If LI is confined to a single basic block, return
/// a pointer to that block. If LI is live in to or out of any block,
/// return NULL.
MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
+ /// Returns true if VNI is killed by any PHI-def values in LI.
+ /// This may conservatively return true to avoid expensive computations.
+ bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
+
/// addKillFlags - Add kill flags to any instruction that kills a virtual
/// register.
void addKillFlags();
@@ -337,13 +311,47 @@ namespace llvm {
bool checkRegMaskInterference(LiveInterval &LI,
BitVector &UsableRegs);
+ // Register unit functions.
+ //
+ // Fixed interference occurs when MachineInstrs use physregs directly
+ // instead of virtual registers. This typically happens when passing
+ // arguments to a function call, or when instructions require operands in
+ // fixed registers.
+ //
+ // Each physreg has one or more register units, see MCRegisterInfo. We
+ // track liveness per register unit to handle aliasing registers more
+ // efficiently.
+
+ /// getRegUnit - Return the live range for Unit.
+ /// It will be computed if it doesn't exist.
+ LiveInterval &getRegUnit(unsigned Unit) {
+ LiveInterval *LI = RegUnitIntervals[Unit];
+ if (!LI) {
+ // Compute missing ranges on demand.
+ RegUnitIntervals[Unit] = LI = new LiveInterval(Unit, HUGE_VALF);
+ computeRegUnitInterval(LI);
+ }
+ return *LI;
+ }
+
+ /// getCachedRegUnit - Return the live range for Unit if it has already
+ /// been computed, or NULL if it hasn't been computed yet.
+ LiveInterval *getCachedRegUnit(unsigned Unit) {
+ return RegUnitIntervals[Unit];
+ }
+
private:
/// computeIntervals - Compute live intervals.
void computeIntervals();
+ /// Compute live intervals for all virtual registers.
+ void computeVirtRegs();
+
+ /// Compute RegMaskSlots and RegMaskBits.
+ void computeRegMasks();
+
/// handleRegisterDef - update intervals for a register def
- /// (calls handlePhysicalRegisterDef and
- /// handleVirtualRegisterDef)
+ /// (calls handleVirtualRegisterDef)
void handleRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI,
SlotIndex MIIdx,
@@ -363,43 +371,15 @@ namespace llvm {
unsigned MOIdx,
LiveInterval& interval);
- /// handlePhysicalRegisterDef - update intervals for a physical register
- /// def.
- void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
- MachineBasicBlock::iterator mi,
- SlotIndex MIIdx, MachineOperand& MO,
- LiveInterval &interval);
-
- /// handleLiveInRegister - Create interval for a livein register.
- void handleLiveInRegister(MachineBasicBlock* mbb,
- SlotIndex MIIdx,
- LiveInterval &interval);
-
- /// getReMatImplicitUse - If the remat definition MI has one (for now, we
- /// only allow one) virtual register operand, then its uses are implicitly
- /// using the register. Returns the virtual register.
- unsigned getReMatImplicitUse(const LiveInterval &li,
- MachineInstr *MI) const;
-
- /// isValNoAvailableAt - Return true if the val# of the specified interval
- /// which reaches the given instruction also reaches the specified use
- /// index.
- bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
- SlotIndex UseIdx) const;
-
- /// isReMaterializable - Returns true if the definition MI of the specified
- /// val# of the specified interval is re-materializable. Also returns true
- /// by reference if the def is a load.
- bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
- MachineInstr *MI,
- const SmallVectorImpl<LiveInterval*> *SpillIs,
- bool &isLoad);
-
static LiveInterval* createInterval(unsigned Reg);
void printInstrs(raw_ostream &O) const;
void dumpInstrs() const;
+ void computeLiveInRegUnits();
+ void computeRegUnitInterval(LiveInterval*);
+ void computeVirtRegInterval(LiveInterval*);
+
class HMEditor;
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index 57a619389fa5..def7b00ce761 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -55,29 +55,29 @@ public:
};
private:
- LiveInterval &parent_;
- SmallVectorImpl<LiveInterval*> &newRegs_;
+ LiveInterval *Parent;
+ SmallVectorImpl<LiveInterval*> &NewRegs;
MachineRegisterInfo &MRI;
LiveIntervals &LIS;
VirtRegMap *VRM;
const TargetInstrInfo &TII;
- Delegate *const delegate_;
+ Delegate *const TheDelegate;
- /// firstNew_ - Index of the first register added to newRegs_.
- const unsigned firstNew_;
+ /// FirstNew - Index of the first register added to NewRegs.
+ const unsigned FirstNew;
- /// scannedRemattable_ - true when remattable values have been identified.
- bool scannedRemattable_;
+ /// ScannedRemattable - true when remattable values have been identified.
+ bool ScannedRemattable;
- /// remattable_ - Values defined by remattable instructions as identified by
+ /// Remattable - Values defined by remattable instructions as identified by
/// tii.isTriviallyReMaterializable().
- SmallPtrSet<const VNInfo*,4> remattable_;
+ SmallPtrSet<const VNInfo*,4> Remattable;
- /// rematted_ - Values that were actually rematted, and so need to have their
+ /// Rematted - Values that were actually rematted, and so need to have their
/// 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);
/// allUsesAvailableAt - Return true if all registers used by OrigMI at
@@ -99,32 +99,35 @@ public:
/// @param vrm Map of virtual registers to physical registers for this
/// function. If NULL, no virtual register map updates will
/// be done. This could be the case if called before Regalloc.
- LiveRangeEdit(LiveInterval &parent,
+ LiveRangeEdit(LiveInterval *parent,
SmallVectorImpl<LiveInterval*> &newRegs,
MachineFunction &MF,
LiveIntervals &lis,
VirtRegMap *vrm,
Delegate *delegate = 0)
- : parent_(parent), newRegs_(newRegs),
+ : Parent(parent), NewRegs(newRegs),
MRI(MF.getRegInfo()), LIS(lis), VRM(vrm),
TII(*MF.getTarget().getInstrInfo()),
- delegate_(delegate),
- firstNew_(newRegs.size()),
- scannedRemattable_(false) {}
+ TheDelegate(delegate),
+ FirstNew(newRegs.size()),
+ ScannedRemattable(false) {}
- LiveInterval &getParent() const { return parent_; }
- unsigned getReg() const { return parent_.reg; }
+ LiveInterval &getParent() const {
+ assert(Parent && "No parent LiveInterval");
+ return *Parent;
+ }
+ unsigned getReg() const { return getParent().reg; }
/// Iterator for accessing the new registers added by this edit.
typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator;
- iterator begin() const { return newRegs_.begin()+firstNew_; }
- iterator end() const { return newRegs_.end(); }
- unsigned size() const { return newRegs_.size()-firstNew_; }
+ iterator begin() const { return NewRegs.begin()+FirstNew; }
+ iterator end() const { return NewRegs.end(); }
+ unsigned size() const { return NewRegs.size()-FirstNew; }
bool empty() const { return size() == 0; }
- LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
+ LiveInterval *get(unsigned idx) const { return NewRegs[idx+FirstNew]; }
ArrayRef<LiveInterval*> regs() const {
- return makeArrayRef(newRegs_).slice(firstNew_);
+ return makeArrayRef(NewRegs).slice(FirstNew);
}
/// createFrom - Create a new virtual register based on OldReg.
@@ -174,12 +177,12 @@ public:
/// markRematerialized - explicitly mark a value as rematerialized after doing
/// it manually.
void markRematerialized(const VNInfo *ParentVNI) {
- rematted_.insert(ParentVNI);
+ Rematted.insert(ParentVNI);
}
/// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
bool didRematerialize(const VNInfo *ParentVNI) const {
- return rematted_.count(ParentVNI);
+ return Rematted.count(ParentVNI);
}
/// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index ef9c0c200584..c917bd8b8183 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -143,10 +143,7 @@ public:
IterTy MII;
public:
- bundle_iterator(IterTy mii) : MII(mii) {
- assert(!MII->isInsideBundle() &&
- "It's not legal to initialize bundle_iterator with a bundled MI");
- }
+ bundle_iterator(IterTy mii) : MII(mii) {}
bundle_iterator(Ty &mi) : MII(mi) {
assert(!mi.isInsideBundle() &&
@@ -156,7 +153,10 @@ public:
assert((!mi || !mi->isInsideBundle()) &&
"It's not legal to initialize bundle_iterator with a bundled MI");
}
- bundle_iterator(const bundle_iterator &I) : MII(I.MII) {}
+ // Template allows conversion from const to nonconst.
+ template<class OtherTy, class OtherIterTy>
+ bundle_iterator(const bundle_iterator<OtherTy, OtherIterTy> &I)
+ : MII(I.getInstrIterator()) {}
bundle_iterator() : MII(0) {}
Ty &operator*() const { return *MII; }
@@ -173,29 +173,24 @@ public:
// Increment and decrement operators...
bundle_iterator &operator--() { // predecrement - Back up
- do {
- --MII;
- } while (MII->isInsideBundle());
+ do --MII;
+ while (MII->isInsideBundle());
return *this;
}
bundle_iterator &operator++() { // preincrement - Advance
- do {
- ++MII;
- } while (MII->isInsideBundle());
+ IterTy E = MII->getParent()->instr_end();
+ do ++MII;
+ while (MII != E && MII->isInsideBundle());
return *this;
}
bundle_iterator operator--(int) { // postdecrement operators...
bundle_iterator tmp = *this;
- do {
- --MII;
- } while (MII->isInsideBundle());
+ --*this;
return tmp;
}
bundle_iterator operator++(int) { // postincrement operators...
bundle_iterator tmp = *this;
- do {
- ++MII;
- } while (MII->isInsideBundle());
+ ++*this;
return tmp;
}
@@ -235,42 +230,14 @@ public:
reverse_instr_iterator instr_rend () { return Insts.rend(); }
const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
- iterator begin() { return Insts.begin(); }
- const_iterator begin() const { return Insts.begin(); }
- iterator end() {
- instr_iterator II = instr_end();
- if (II != instr_begin()) {
- while (II->isInsideBundle())
- --II;
- }
- return II;
- }
- const_iterator end() const {
- const_instr_iterator II = instr_end();
- if (II != instr_begin()) {
- while (II->isInsideBundle())
- --II;
- }
- return II;
- }
- reverse_iterator rbegin() {
- reverse_instr_iterator II = instr_rbegin();
- if (II != instr_rend()) {
- while (II->isInsideBundle())
- ++II;
- }
- return II;
- }
- const_reverse_iterator rbegin() const {
- const_reverse_instr_iterator II = instr_rbegin();
- if (II != instr_rend()) {
- while (II->isInsideBundle())
- ++II;
- }
- return II;
- }
- reverse_iterator rend () { return Insts.rend(); }
- const_reverse_iterator rend () const { return Insts.rend(); }
+ iterator begin() { return instr_begin(); }
+ const_iterator begin() const { return instr_begin(); }
+ iterator end () { return instr_end(); }
+ const_iterator end () const { return instr_end(); }
+ reverse_iterator rbegin() { return instr_rbegin(); }
+ const_reverse_iterator rbegin() const { return instr_rbegin(); }
+ reverse_iterator rend () { return instr_rend(); }
+ const_reverse_iterator rend () const { return instr_rend(); }
// Machine-CFG iterators
@@ -412,6 +379,10 @@ public:
/// which refer to fromMBB to refer to this.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB);
+ /// isPredecessor - Return true if the specified MBB is a predecessor of this
+ /// block.
+ bool isPredecessor(const MachineBasicBlock *MBB) const;
+
/// isSuccessor - Return true if the specified MBB is a successor of this
/// block.
bool isSuccessor(const MachineBasicBlock *MBB) const;
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 44402a9e68fb..8b958e437ed3 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -359,7 +359,7 @@ public:
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
- MaxAlignment = std::max(MaxAlignment, Align);
+ ensureMaxAlignment(Align);
}
/// NeedsStackProtector - Returns true if the object may need stack
@@ -416,9 +416,11 @@ public:
///
unsigned getMaxAlignment() const { return MaxAlignment; }
- /// setMaxAlignment - Set the preferred alignment.
- ///
- void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
+ /// ensureMaxAlignment - Make sure the function is at least Align bytes
+ /// aligned.
+ void ensureMaxAlignment(unsigned Align) {
+ if (MaxAlignment < Align) MaxAlignment = Align;
+ }
/// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
/// when calling another function. This is only valid during and after
@@ -485,7 +487,7 @@ public:
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
int Index = (int)Objects.size() - NumFixedObjects - 1;
assert(Index >= 0 && "Bad frame index!");
- MaxAlignment = std::max(MaxAlignment, Alignment);
+ ensureMaxAlignment(Alignment);
return Index;
}
@@ -496,7 +498,7 @@ public:
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
CreateStackObject(Size, Alignment, true, false);
int Index = (int)Objects.size() - NumFixedObjects - 1;
- MaxAlignment = std::max(MaxAlignment, Alignment);
+ ensureMaxAlignment(Alignment);
return Index;
}
@@ -515,7 +517,7 @@ public:
int CreateVariableSizedObject(unsigned Alignment) {
HasVarSizedObjects = true;
Objects.push_back(StackObject(0, Alignment, 0, false, false, true));
- MaxAlignment = std::max(MaxAlignment, Alignment);
+ ensureMaxAlignment(Alignment);
return (int)Objects.size()-NumFixedObjects-1;
}
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index dda2dc708769..062c7508c496 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -189,8 +189,8 @@ public:
///
void setAlignment(unsigned A) { Alignment = A; }
- /// EnsureAlignment - Make sure the function is at least 1 << A bytes aligned.
- void EnsureAlignment(unsigned A) {
+ /// ensureAlignment - Make sure the function is at least 1 << A bytes aligned.
+ void ensureAlignment(unsigned A) {
if (Alignment < A) Alignment = A;
}
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 65093d7e7ad6..4c5eb8b36f36 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -635,6 +635,30 @@ public:
getOperand(0).getSubReg() == getOperand(1).getSubReg();
}
+ /// isTransient - Return true if this is a transient instruction that is
+ /// either very likely to be eliminated during register allocation (such as
+ /// copy-like instructions), or if this instruction doesn't have an
+ /// execution-time cost.
+ bool isTransient() const {
+ switch(getOpcode()) {
+ default: return false;
+ // Copy-like instructions are usually eliminated during register allocation.
+ case TargetOpcode::PHI:
+ case TargetOpcode::COPY:
+ case TargetOpcode::INSERT_SUBREG:
+ case TargetOpcode::SUBREG_TO_REG:
+ case TargetOpcode::REG_SEQUENCE:
+ // Pseudo-instructions that don't produce any real output.
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::PROLOG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
+ case TargetOpcode::DBG_VALUE:
+ return true;
+ }
+ }
+
/// getBundleSize - Return the number of instructions inside the MI bundle.
unsigned getBundleSize() const;
@@ -912,12 +936,12 @@ private:
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists.
- void RemoveRegOperandsFromUseLists();
+ void RemoveRegOperandsFromUseLists(MachineRegisterInfo&);
/// AddRegOperandsToUseLists - Add all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands not be on their use lists yet.
- void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo);
+ void AddRegOperandsToUseLists(MachineRegisterInfo&);
/// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a
/// bundle.
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 99849a64c56a..654361f9d423 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -34,6 +34,7 @@ namespace RegState {
Undef = 0x20,
EarlyClobber = 0x40,
Debug = 0x80,
+ InternalRead = 0x100,
DefineNoRead = Define | Undef,
ImplicitDefine = Implicit | Define,
ImplicitKill = Implicit | Kill
@@ -67,7 +68,8 @@ public:
flags & RegState::Undef,
flags & RegState::EarlyClobber,
SubReg,
- flags & RegState::Debug));
+ flags & RegState::Debug,
+ flags & RegState::InternalRead));
return *this;
}
@@ -106,6 +108,12 @@ public:
return *this;
}
+ const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags));
+ return *this;
+ }
+
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
@@ -310,6 +318,9 @@ inline unsigned getDeadRegState(bool B) {
inline unsigned getUndefRegState(bool B) {
return B ? RegState::Undef : 0;
}
+inline unsigned getInternalReadRegState(bool B) {
+ return B ? RegState::InternalRead : 0;
+}
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
index 0fb496982276..dc5f9a6ec82d 100644
--- a/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -43,14 +43,14 @@ bool finalizeBundles(MachineFunction &MF);
/// getBundleStart - Returns the first instruction in the bundle containing MI.
///
-static inline MachineInstr *getBundleStart(MachineInstr *MI) {
+inline MachineInstr *getBundleStart(MachineInstr *MI) {
MachineBasicBlock::instr_iterator I = MI;
while (I->isInsideBundle())
--I;
return I;
}
-static inline const MachineInstr *getBundleStart(const MachineInstr *MI) {
+inline const MachineInstr *getBundleStart(const MachineInstr *MI) {
MachineBasicBlock::const_instr_iterator I = MI;
while (I->isInsideBundle())
--I;
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index 6bd6682dd39c..f7c4e8642d53 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -10,9 +10,9 @@
// The MachineJumpTableInfo class keeps track of jump tables referenced by
// lowered switch instructions in the MachineFunction.
//
-// Instructions reference the address of these jump tables through the use of
-// MO_JumpTableIndex values. When emitting assembly or machine code, these
-// virtual address references are converted to refer to the address of the
+// Instructions reference the address of these jump tables through the use of
+// MO_JumpTableIndex values. When emitting assembly or machine code, these
+// virtual address references are converted to refer to the address of the
// function jump tables.
//
//===----------------------------------------------------------------------===//
@@ -34,11 +34,11 @@ class raw_ostream;
struct MachineJumpTableEntry {
/// MBBs - The vector of basic blocks from which to create the jump table.
std::vector<MachineBasicBlock*> MBBs;
-
+
explicit MachineJumpTableEntry(const std::vector<MachineBasicBlock*> &M)
: MBBs(M) {}
};
-
+
class MachineJumpTableInfo {
public:
/// JTEntryKind - This enum indicates how each entry of the jump table is
@@ -57,7 +57,7 @@ public:
/// with a relocation as gp-relative, e.g.:
/// .gprel32 LBB123
EK_GPRel32BlockAddress,
-
+
/// EK_LabelDifference32 - Each entry is the address of the block minus
/// the address of the jump table. This is used for PIC jump tables where
/// gprel32 is not supported. e.g.:
@@ -80,18 +80,18 @@ private:
std::vector<MachineJumpTableEntry> JumpTables;
public:
explicit MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
-
+
JTEntryKind getEntryKind() const { return EntryKind; }
/// getEntrySize - Return the size of each entry in the jump table.
unsigned getEntrySize(const TargetData &TD) const;
/// getEntryAlignment - Return the alignment of each entry in the jump table.
unsigned getEntryAlignment(const TargetData &TD) const;
-
+
/// createJumpTableIndex - Create a new jump table.
///
unsigned createJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
-
+
/// isEmpty - Return true if there are no jump tables.
///
bool isEmpty() const { return JumpTables.empty(); }
@@ -105,7 +105,7 @@ public:
void RemoveJumpTable(unsigned Idx) {
JumpTables[Idx].MBBs.clear();
}
-
+
/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
/// the jump tables to branch to New instead.
bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New);
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 6dd9440500bf..3e204bed15ad 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the MachineLoopInfo class that is used to identify natural
+// This file defines the MachineLoopInfo class that is used to identify natural
// loops and determine the loop depth of various nodes of the CFG. Note that
// natural loops may actually be several loops that share the same header node.
//
@@ -35,6 +35,12 @@
namespace llvm {
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+class MachineLoop;
+__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop>;
+#endif
+
class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
public:
MachineLoop();
@@ -57,6 +63,12 @@ private:
: LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}
};
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template
+class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+#endif
+
class MachineLoopInfo : public MachineFunctionPass {
LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
friend class LoopBase<MachineBasicBlock, MachineLoop>;
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index d244dd92103d..37d42b358382 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
#define LLVM_CODEGEN_MACHINEOPERAND_H
+#include "llvm/ADT/Hashing.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -44,6 +45,7 @@ public:
MO_MachineBasicBlock, ///< MachineBasicBlock reference
MO_FrameIndex, ///< Abstract Stack Frame Index
MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
+ MO_TargetIndex, ///< Target-dependent index+offset operand.
MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
MO_ExternalSymbol, ///< Name of external global symbol
MO_GlobalAddress, ///< Address of a global value
@@ -148,7 +150,7 @@ private:
struct { // For MO_Register.
// Register number is in SmallContents.RegNo.
- MachineOperand **Prev; // Access list for register.
+ MachineOperand *Prev; // Access list for register. See MRI.
MachineOperand *Next;
} Reg;
@@ -214,6 +216,8 @@ public:
bool isFI() const { return OpKind == MO_FrameIndex; }
/// isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
+ /// isTargetIndex - Tests if this is a MO_TargetIndex operand.
+ bool isTargetIndex() const { return OpKind == MO_TargetIndex; }
/// isJTI - Tests if this is a MO_JumpTableIndex operand.
bool isJTI() const { return OpKind == MO_JumpTableIndex; }
/// isGlobal - Tests if this is a MO_GlobalAddress operand.
@@ -301,13 +305,6 @@ public:
return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
}
- /// getNextOperandForReg - Return the next MachineOperand in the function that
- /// uses or defines this register.
- MachineOperand *getNextOperandForReg() const {
- assert(isReg() && "This is not a register operand!");
- return Contents.Reg.Next;
- }
-
//===--------------------------------------------------------------------===//
// Mutators for Register Operands
//===--------------------------------------------------------------------===//
@@ -334,17 +331,9 @@ public:
///
void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
- void setIsUse(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert((Val || !isDebug()) && "Marking a debug operation as def");
- IsDef = !Val;
- }
+ void setIsUse(bool Val = true) { setIsDef(!Val); }
- void setIsDef(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert((!Val || !isDebug()) && "Marking a debug operation as def");
- IsDef = Val;
- }
+ void setIsDef(bool Val = true);
void setImplicit(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
@@ -407,7 +396,7 @@ public:
}
int getIndex() const {
- assert((isFI() || isCPI() || isJTI()) &&
+ assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
"Wrong MachineOperand accessor");
return Contents.OffsetedInfo.Val.Index;
}
@@ -430,8 +419,8 @@ public:
/// getOffset - Return the offset from the symbol in this operand. This always
/// returns 0 for ExternalSymbol operands.
int64_t getOffset() const {
- assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
- "Wrong MachineOperand accessor");
+ assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
+ isBlockAddress()) && "Wrong MachineOperand accessor");
return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
SmallContents.OffsetLo;
}
@@ -478,14 +467,14 @@ public:
}
void setOffset(int64_t Offset) {
- assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
- "Wrong MachineOperand accessor");
+ assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
+ isBlockAddress()) && "Wrong MachineOperand accessor");
SmallContents.OffsetLo = unsigned(Offset);
Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
}
void setIndex(int Idx) {
- assert((isFI() || isCPI() || isJTI()) &&
+ assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
"Wrong MachineOperand accessor");
Contents.OffsetedInfo.Val.Index = Idx;
}
@@ -503,6 +492,13 @@ public:
/// operand. Note: This method ignores isKill and isDead properties.
bool isIdenticalTo(const MachineOperand &Other) const;
+ /// \brief MachineOperand hash_value overload.
+ ///
+ /// Note that this includes the same information in the hash that
+ /// isIdenticalTo uses for comparison. It is thus suited for use in hash
+ /// tables which use that function for equality comparisons only.
+ friend hash_code hash_value(const MachineOperand &MO);
+
/// ChangeToImmediate - Replace this operand with a new immediate operand of
/// the specified value. If an operand is known to be an immediate already,
/// the setImm method should be used.
@@ -542,14 +538,15 @@ public:
bool isUndef = false,
bool isEarlyClobber = false,
unsigned SubReg = 0,
- bool isDebug = false) {
+ bool isDebug = false,
+ bool isInternalRead = false) {
MachineOperand Op(MachineOperand::MO_Register);
Op.IsDef = isDef;
Op.IsImp = isImp;
Op.IsKill = isKill;
Op.IsDead = isDead;
Op.IsUndef = isUndef;
- Op.IsInternalRead = false;
+ Op.IsInternalRead = isInternalRead;
Op.IsEarlyClobber = isEarlyClobber;
Op.IsDebug = isDebug;
Op.SmallContents.RegNo = Reg;
@@ -578,6 +575,14 @@ public:
Op.setTargetFlags(TargetFlags);
return Op;
}
+ static MachineOperand CreateTargetIndex(unsigned Idx, int64_t Offset,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_TargetIndex);
+ Op.setIndex(Idx);
+ Op.setOffset(Offset);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
static MachineOperand CreateJTI(unsigned Idx,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_JumpTableIndex);
@@ -653,15 +658,6 @@ private:
assert(isReg() && "Can only add reg operand to use lists");
return Contents.Reg.Prev != 0;
}
-
- /// AddRegOperandToRegInfo - Add this register operand to the specified
- /// MachineRegisterInfo. If it is null, then the next/prev fields should be
- /// explicitly nulled out.
- void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
-
- /// RemoveRegOperandFromRegInfo - Remove this register operand from the
- /// MachineRegisterInfo it is linked with.
- void RemoveRegOperandFromRegInfo();
};
inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
index c41e8e26d66a..90ee7f4bb9e7 100644
--- a/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -26,7 +26,7 @@ namespace llvm {
typedef void *(*MachinePassCtor)();
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
///
/// MachinePassRegistryListener - Listener to adds and removals of nodes in
/// registration list.
@@ -42,7 +42,7 @@ public:
};
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
///
/// MachinePassRegistryNode - Machine pass node stored in registration list.
///
@@ -55,7 +55,7 @@ private:
const char *Name; // Name of function pass.
const char *Description; // Description string.
MachinePassCtor Ctor; // Function pass creator.
-
+
public:
MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
@@ -72,11 +72,11 @@ public:
const char *getDescription() const { return Description; }
MachinePassCtor getCtor() const { return Ctor; }
void setNext(MachinePassRegistryNode *N) { Next = N; }
-
+
};
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
///
/// MachinePassRegistry - Track the registration of machine passes.
///
@@ -88,7 +88,7 @@ private:
MachinePassRegistryNode *List; // List of registry nodes.
MachinePassCtor Default; // Default function pass creator.
MachinePassRegistryListener* Listener;// Listener for list adds are removes.
-
+
public:
// NO CONSTRUCTOR - we don't want static constructor ordering to mess
@@ -99,6 +99,7 @@ public:
MachinePassRegistryNode *getList() { return List; }
MachinePassCtor getDefault() { return Default; }
void setDefault(MachinePassCtor C) { Default = C; }
+ void setDefault(StringRef Name);
void setListener(MachinePassRegistryListener *L) { Listener = L; }
/// Add - Adds a function pass to the registration list.
@@ -126,7 +127,7 @@ public:
void initialize(cl::Option &O) {
cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O);
-
+
// Add existing passes to option.
for (RegistryClass *Node = RegistryClass::getList();
Node; Node = Node->getNext()) {
@@ -134,7 +135,7 @@ public:
(typename RegistryClass::FunctionPassCtor)Node->getCtor(),
Node->getDescription());
}
-
+
// Make sure we listen for list changes.
RegistryClass::setListener(this);
}
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 3272fbd78ff5..42a8aa43d982 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -57,6 +57,26 @@ class MachineRegisterInfo {
/// physical registers.
MachineOperand **PhysRegUseDefLists;
+ /// getRegUseDefListHead - Return the head pointer for the register use/def
+ /// list for the specified virtual or physical register.
+ MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
+ }
+
+ MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
+ }
+
+ /// Get the next element in the use-def chain.
+ static MachineOperand *getNextOperandForReg(const MachineOperand *MO) {
+ assert(MO && MO->isReg() && "This is not a register operand!");
+ return MO->Contents.Reg.Next;
+ }
+
/// UsedPhysRegs - This is a bit vector that is computed and set by the
/// register allocator, and must be kept up to date by passes that run after
/// register allocation (though most don't modify this). This is used
@@ -129,12 +149,21 @@ public:
// Register Info
//===--------------------------------------------------------------------===//
+ // Strictly for use by MachineInstr.cpp.
+ void addRegOperandToUseList(MachineOperand *MO);
+
+ // Strictly for use by MachineInstr.cpp.
+ void removeRegOperandFromUseList(MachineOperand *MO);
+
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
/// and uses of a register within the MachineFunction that corresponds to this
/// MachineRegisterInfo object.
template<bool Uses, bool Defs, bool SkipDebug>
class defusechain_iterator;
+ // Make it a friend so it can access getNextOperandForReg().
+ template<bool, bool, bool> friend class defusechain_iterator;
+
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
/// register.
typedef defusechain_iterator<true,true,false> reg_iterator;
@@ -172,6 +201,15 @@ public:
/// specified register (it may be live-in).
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
+ /// hasOneDef - Return true if there is exactly one instruction defining the
+ /// specified register.
+ bool hasOneDef(unsigned RegNo) const {
+ def_iterator DI = def_begin(RegNo);
+ if (DI == def_end())
+ return false;
+ return ++DI == def_end();
+ }
+
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
typedef defusechain_iterator<true,false,false> use_iterator;
use_iterator use_begin(unsigned RegNo) const {
@@ -185,7 +223,12 @@ public:
/// hasOneUse - Return true if there is exactly one instruction using the
/// specified register.
- bool hasOneUse(unsigned RegNo) const;
+ bool hasOneUse(unsigned RegNo) const {
+ use_iterator UI = use_begin(RegNo);
+ if (UI == use_end())
+ return false;
+ return ++UI == use_end();
+ }
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
/// specified register, skipping those marked as Debug.
@@ -218,25 +261,16 @@ public:
/// constraints.
void replaceRegWith(unsigned FromReg, unsigned ToReg);
- /// getRegUseDefListHead - Return the head pointer for the register use/def
- /// list for the specified virtual or physical register.
- MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
- if (TargetRegisterInfo::isVirtualRegister(RegNo))
- return VRegInfo[RegNo].second;
- return PhysRegUseDefLists[RegNo];
- }
-
- MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
- if (TargetRegisterInfo::isVirtualRegister(RegNo))
- return VRegInfo[RegNo].second;
- return PhysRegUseDefLists[RegNo];
- }
-
/// getVRegDef - Return the machine instr that defines the specified virtual
/// register or null if none is found. This assumes that the code is in SSA
/// form, so there should only be one definition.
MachineInstr *getVRegDef(unsigned Reg) const;
+ /// getUniqueVRegDef - Return the unique machine instr that defines the
+ /// specified virtual register or null if none is found. If there are
+ /// multiple definitions or no definition, return null.
+ MachineInstr *getUniqueVRegDef(unsigned Reg) const;
+
/// clearKillFlags - Iterate over all the uses of the given register and
/// clear the kill flag from the MachineOperand. This function is used by
/// optimization passes which extend register lifetimes and need only
@@ -336,7 +370,7 @@ public:
bool isPhysRegOrOverlapUsed(unsigned Reg) const {
if (UsedPhysRegMask.test(Reg))
return true;
- for (const uint16_t *AI = TRI->getOverlaps(Reg); *AI; ++AI)
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
if (UsedPhysRegs.test(*AI))
return true;
return false;
@@ -434,10 +468,6 @@ public:
const TargetRegisterInfo &TRI,
const TargetInstrInfo &TII);
-private:
- void HandleVRegListReallocation();
-
-public:
/// defusechain_iterator - This class provides iterator support for machine
/// operands in the function that use or define a specific register. If
/// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
@@ -481,13 +511,22 @@ public:
// Iterator traversal: forward iteration only
defusechain_iterator &operator++() { // Preincrement
assert(Op && "Cannot increment end iterator!");
- Op = Op->getNextOperandForReg();
-
- // If this is an operand we don't care about, skip it.
- while (Op && ((!ReturnUses && Op->isUse()) ||
- (!ReturnDefs && Op->isDef()) ||
- (SkipDebug && Op->isDebug())))
- Op = Op->getNextOperandForReg();
+ Op = getNextOperandForReg(Op);
+
+ // All defs come before the uses, so stop def_iterator early.
+ if (!ReturnUses) {
+ if (Op) {
+ if (Op->isUse())
+ Op = 0;
+ else
+ assert(!Op->isDebug() && "Can't have debug defs");
+ }
+ } else {
+ // If this is an operand we don't care about, skip it.
+ while (Op && ((!ReturnDefs && Op->isDef()) ||
+ (SkipDebug && Op->isDebug())))
+ Op = getNextOperandForReg(Op);
+ }
return *this;
}
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index e852009f7e8b..8da2045ad0be 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -19,7 +19,7 @@
// createCustomMachineSched);
//
// Inside <Target>PassConfig:
-// enablePass(MachineSchedulerID);
+// enablePass(&MachineSchedulerID);
// MachineSchedRegistry::setDefault(createCustomMachineSched);
//
//===----------------------------------------------------------------------===//
@@ -35,6 +35,7 @@ class AliasAnalysis;
class LiveIntervals;
class MachineDominatorTree;
class MachineLoopInfo;
+class RegisterClassInfo;
class ScheduleDAGInstrs;
/// MachineSchedContext provides enough context from the MachineScheduler pass
@@ -47,7 +48,10 @@ struct MachineSchedContext {
AliasAnalysis *AA;
LiveIntervals *LIS;
- MachineSchedContext(): MF(0), MLI(0), MDT(0), PassConfig(0), AA(0), LIS(0) {}
+ RegisterClassInfo *RegClassInfo;
+
+ MachineSchedContext();
+ virtual ~MachineSchedContext();
};
/// MachineSchedRegistry provides a selection of available machine instruction
@@ -81,6 +85,9 @@ public:
static void setDefault(ScheduleDAGCtor C) {
Registry.setDefault((MachinePassCtor)C);
}
+ static void setDefault(StringRef Name) {
+ Registry.setDefault(Name);
+ }
static void setListener(MachinePassRegistryListener *L) {
Registry.setListener(L);
}
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index e76fe9925721..07b3b45873ae 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -24,6 +24,7 @@ namespace llvm {
class FunctionPass;
class MachineFunctionPass;
class PassInfo;
+ class PassManagerBase;
class TargetLowering;
class TargetRegisterClass;
class raw_ostream;
@@ -31,8 +32,6 @@ namespace llvm {
namespace llvm {
-extern char &NoPassID; // Allow targets to choose not to run a pass.
-
class PassConfigImpl;
/// Target-Independent Code Generator Pass Configuration Options.
@@ -54,9 +53,15 @@ public:
/// optimization after regalloc.
static char PostRAMachineLICMID;
+private:
+ PassManagerBase *PM;
+ AnalysisID StartAfter;
+ AnalysisID StopAfter;
+ bool Started;
+ bool Stopped;
+
protected:
TargetMachine *TM;
- PassManagerBase *PM;
PassConfigImpl *Impl; // Internal data structures
bool Initialized; // Flagged after all passes are configured.
@@ -91,6 +96,18 @@ public:
CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
+ /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
+ /// running only a portion of the normal code-gen pass sequence. If the
+ /// Start pass ID is zero, then compilation will begin at the normal point;
+ /// otherwise, clear the Started flag to indicate that passes should not be
+ /// added until the starting pass is seen. If the Stop pass ID is zero,
+ /// then compilation will continue to the end.
+ void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
+ StartAfter = Start;
+ StopAfter = Stop;
+ Started = (StartAfter == 0);
+ }
+
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
bool getEnableTailMerge() const { return EnableTailMerge; }
@@ -98,16 +115,19 @@ public:
/// Allow the target to override a specific pass without overriding the pass
/// pipeline. When passes are added to the standard pipeline at the
- /// point where StadardID is expected, add TargetID in its place.
- void substitutePass(char &StandardID, char &TargetID);
+ /// point where StandardID is expected, add TargetID in its place.
+ void substitutePass(AnalysisID StandardID, AnalysisID TargetID);
+
+ /// Insert InsertedPassID pass after TargetPassID pass.
+ void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID);
/// Allow the target to enable a specific standard pass by default.
- void enablePass(char &ID) { substitutePass(ID, ID); }
+ void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
/// Allow the target to disable a specific standard pass by default.
- void disablePass(char &ID) { substitutePass(ID, NoPassID); }
+ void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); }
- /// Return the pass ssubtituted for StandardID by the target.
+ /// Return the pass substituted for StandardID by the target.
/// If no substitution exists, return StandardID.
AnalysisID getPassSubstitution(AnalysisID StandardID) const;
@@ -118,6 +138,9 @@ public:
/// transforms following machine independent optimization.
virtual void addIRPasses();
+ /// Add passes to lower exception handling for the code generator.
+ void addPassesToHandleExceptions();
+
/// Add common passes that perform LLVM IR to IR transforms in preparation for
/// instruction selection.
virtual void addISelPrepare();
@@ -172,6 +195,18 @@ protected:
/// LLVMTargetMachine provides standard regalloc passes for most targets.
virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
+ /// addPreRewrite - Add passes to the optimized register allocation pipeline
+ /// after register allocation is complete, but before virtual registers are
+ /// rewritten to physical registers.
+ ///
+ /// These passes must preserve VirtRegMap and LiveIntervals, and when running
+ /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
+ /// When these passes run, VirtRegMap contains legal physreg assignments for
+ /// all virtual registers.
+ virtual bool addPreRewrite() {
+ return false;
+ }
+
/// addFinalizeRegAlloc - This method may be implemented by targets that want
/// to run passes within the regalloc pipeline, immediately after the register
/// allocation pass itself. These passes run as soon as virtual regisiters
@@ -216,8 +251,12 @@ protected:
///
/// Add a CodeGen pass at this point in the pipeline after checking overrides.
- /// Return the pass that was added, or NoPassID.
- AnalysisID addPass(char &ID);
+ /// Return the pass that was added, or zero if no pass was added.
+ AnalysisID addPass(AnalysisID PassID);
+
+ /// Add a pass to the PassManager if that pass is supposed to be run, as
+ /// determined by the StartAfter and StopAfter options.
+ void addPass(Pass *P);
/// addMachinePasses helper to create the target-selected or overriden
/// regalloc pass.
@@ -226,7 +265,7 @@ protected:
/// printAndVerify - Add a pass to dump then verify the machine function, if
/// those steps are enabled.
///
- void printAndVerify(const char *Banner) const;
+ void printAndVerify(const char *Banner);
};
} // namespace llvm
@@ -276,6 +315,10 @@ namespace llvm {
/// This pass is still in development
extern char &StrongPHIEliminationID;
+ /// LiveIntervals - This analysis keeps track of the live ranges of virtual
+ /// and physical registers.
+ extern char &LiveIntervalsID;
+
/// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
extern char &LiveStacksID;
@@ -297,6 +340,10 @@ namespace llvm {
/// basic blocks.
extern char &SpillPlacementID;
+ /// VirtRegRewriter pass. Rewrite virtual registers to physical registers as
+ /// assigned in VirtRegMap.
+ extern char &VirtRegRewriterID;
+
/// UnreachableMachineBlockElimination - This pass removes unreachable
/// machine basic blocks.
extern char &UnreachableMachineBlockElimID;
@@ -342,10 +389,21 @@ namespace llvm {
/// branches.
extern char &BranchFolderPassID;
+ /// MachineFunctionPrinterPass - This pass prints out MachineInstr's.
+ extern char &MachineFunctionPrinterPassID;
+
/// TailDuplicate - Duplicate blocks with unconditional branches
/// into tails of their predecessors.
extern char &TailDuplicateID;
+ /// MachineTraceMetrics - This pass computes critical path and CPU resource
+ /// usage in an ensemble of traces.
+ extern char &MachineTraceMetricsID;
+
+ /// EarlyIfConverter - This pass performs if-conversion on SSA form by
+ /// inserting cmov instructions.
+ extern char &EarlyIfConverterID;
+
/// IfConverter - This pass performs machine code if conversion.
extern char &IfConverterID;
diff --git a/include/llvm/CodeGen/ProcessImplicitDefs.h b/include/llvm/CodeGen/ProcessImplicitDefs.h
deleted file mode 100644
index 6ab57f03aee7..000000000000
--- a/include/llvm/CodeGen/ProcessImplicitDefs.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-------------- llvm/CodeGen/ProcessImplicitDefs.h ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
-#define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
-
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/ADT/SmallSet.h"
-
-namespace llvm {
-
- class MachineInstr;
- class TargetInstrInfo;
- class TargetRegisterInfo;
- class MachineRegisterInfo;
- class LiveVariables;
-
- /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def
- /// for each use. Add isUndef marker to implicit_def defs and their uses.
- class ProcessImplicitDefs : public MachineFunctionPass {
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- MachineRegisterInfo *MRI;
- LiveVariables *LV;
-
- bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
- unsigned OpIdx,
- SmallSet<unsigned, 8> &ImpDefRegs);
-
- public:
- static char ID;
-
- ProcessImplicitDefs() : MachineFunctionPass(ID) {
- initializeProcessImplicitDefsPass(*PassRegistry::getPassRegistry());
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &au) const;
-
- virtual bool runOnMachineFunction(MachineFunction &fn);
- };
-
-}
-
-#endif // LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
new file mode 100644
index 000000000000..400e1f48ce54
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -0,0 +1,132 @@
+//===-- RegisterClassInfo.h - Dynamic Register Class Info -*- C++ -*-------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RegisterClassInfo class which provides dynamic
+// information about target register classes. Callee saved and reserved
+// registers depends on calling conventions and other dynamic information, so
+// some things cannot be determined statically.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTERCLASSINFO_H
+#define LLVM_CODEGEN_REGISTERCLASSINFO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+
+class RegisterClassInfo {
+ struct RCInfo {
+ unsigned Tag;
+ unsigned NumRegs;
+ bool ProperSubClass;
+ OwningArrayPtr<unsigned> Order;
+
+ RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {}
+ operator ArrayRef<unsigned>() const {
+ return makeArrayRef(Order.get(), NumRegs);
+ }
+ };
+
+ // Brief cached information for each register class.
+ OwningArrayPtr<RCInfo> RegClass;
+
+ // Tag changes whenever cached information needs to be recomputed. An RCInfo
+ // entry is valid when its tag matches.
+ unsigned Tag;
+
+ const MachineFunction *MF;
+ const TargetRegisterInfo *TRI;
+
+ // Callee saved registers of last MF. Assumed to be valid until the next
+ // runOnFunction() call.
+ const uint16_t *CalleeSaved;
+
+ // Map register number to CalleeSaved index + 1;
+ SmallVector<uint8_t, 4> CSRNum;
+
+ // Reserved registers in the current MF.
+ BitVector Reserved;
+
+ // Compute all information about RC.
+ void compute(const TargetRegisterClass *RC) const;
+
+ // Return an up-to-date RCInfo for RC.
+ const RCInfo &get(const TargetRegisterClass *RC) const {
+ const RCInfo &RCI = RegClass[RC->getID()];
+ if (Tag != RCI.Tag)
+ compute(RC);
+ return RCI;
+ }
+
+public:
+ RegisterClassInfo();
+
+ /// runOnFunction - Prepare to answer questions about MF. This must be called
+ /// before any other methods are used.
+ void runOnMachineFunction(const MachineFunction &MF);
+
+ /// getNumAllocatableRegs - Returns the number of actually allocatable
+ /// registers in RC in the current function.
+ unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const {
+ return get(RC).NumRegs;
+ }
+
+ /// getOrder - Returns the preferred allocation order for RC. The order
+ /// contains no reserved registers, and registers that alias callee saved
+ /// registers come last.
+ ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const {
+ return get(RC);
+ }
+
+ /// isProperSubClass - Returns true if RC has a legal super-class with more
+ /// allocatable registers.
+ ///
+ /// Register classes like GR32_NOSP are not proper sub-classes because %esp
+ /// is not allocatable. Similarly, tGPR is not a proper sub-class in Thumb
+ /// mode because the GPR super-class is not legal.
+ bool isProperSubClass(const TargetRegisterClass *RC) const {
+ return get(RC).ProperSubClass;
+ }
+
+ /// getLastCalleeSavedAlias - Returns the last callee saved register that
+ /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR.
+ unsigned getLastCalleeSavedAlias(unsigned PhysReg) const {
+ assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
+ if (unsigned N = CSRNum[PhysReg])
+ return CalleeSaved[N-1];
+ return 0;
+ }
+
+ /// isReserved - Returns true when PhysReg is a reserved register.
+ ///
+ /// Reserved registers may belong to an allocatable register class, but the
+ /// target has explicitly requested that they are not used.
+ ///
+ bool isReserved(unsigned PhysReg) const {
+ return Reserved.test(PhysReg);
+ }
+
+ /// isAllocatable - Returns true when PhysReg belongs to an allocatable
+ /// register class and it hasn't been reserved.
+ ///
+ /// Allocatable registers may show up in the allocation order of some virtual
+ /// register, so a register allocator needs to track its liveness and
+ /// availability.
+ bool isAllocatable(unsigned PhysReg) const {
+ return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg);
+ }
+};
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
new file mode 100644
index 000000000000..2043155bc53f
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -0,0 +1,282 @@
+//===-- RegisterPressure.h - Dynamic Register Pressure -*- C++ -*-------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RegisterPressure class which can be used to track
+// MachineInstr level register pressure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
+#define LLVM_CODEGEN_REGISTERPRESSURE_H
+
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/SparseSet.h"
+
+namespace llvm {
+
+class LiveIntervals;
+class RegisterClassInfo;
+class MachineInstr;
+
+/// Base class for register pressure results.
+struct RegisterPressure {
+ /// Map of max reg pressure indexed by pressure set ID, not class ID.
+ std::vector<unsigned> MaxSetPressure;
+
+ /// List of live in registers.
+ SmallVector<unsigned,8> LiveInRegs;
+ SmallVector<unsigned,8> LiveOutRegs;
+
+ /// Increase register pressure for each pressure set impacted by this register
+ /// class. Normally called by RegPressureTracker, but may be called manually
+ /// to account for live through (global liveness).
+ void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
+
+ /// Decrease register pressure for each pressure set impacted by this register
+ /// class. This is only useful to account for spilling or rematerialization.
+ void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
+
+ void dump(const TargetRegisterInfo *TRI);
+};
+
+/// RegisterPressure computed within a region of instructions delimited by
+/// TopIdx and BottomIdx. During pressure computation, the maximum pressure per
+/// register pressure set is increased. Once pressure within a region is fully
+/// computed, the live-in and live-out sets are recorded.
+///
+/// This is preferable to RegionPressure when LiveIntervals are available,
+/// because delimiting regions by SlotIndex is more robust and convenient than
+/// holding block iterators. The block contents can change without invalidating
+/// the pressure result.
+struct IntervalPressure : RegisterPressure {
+ /// Record the boundary of the region being tracked.
+ SlotIndex TopIdx;
+ SlotIndex BottomIdx;
+
+ void reset();
+
+ void openTop(SlotIndex NextTop);
+
+ void openBottom(SlotIndex PrevBottom);
+};
+
+/// RegisterPressure computed within a region of instructions delimited by
+/// TopPos and BottomPos. This is a less precise version of IntervalPressure for
+/// use when LiveIntervals are unavailable.
+struct RegionPressure : RegisterPressure {
+ /// Record the boundary of the region being tracked.
+ MachineBasicBlock::const_iterator TopPos;
+ MachineBasicBlock::const_iterator BottomPos;
+
+ void reset();
+
+ void openTop(MachineBasicBlock::const_iterator PrevTop);
+
+ void openBottom(MachineBasicBlock::const_iterator PrevBottom);
+};
+
+/// An element of pressure difference that identifies the pressure set and
+/// amount of increase or decrease in units of pressure.
+struct PressureElement {
+ unsigned PSetID;
+ int UnitIncrease;
+
+ PressureElement(): PSetID(~0U), UnitIncrease(0) {}
+ PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc) {}
+
+ bool isValid() const { return PSetID != ~0U; }
+};
+
+/// Store the effects of a change in pressure on things that MI scheduler cares
+/// about.
+///
+/// Excess records the value of the largest difference in register units beyond
+/// the target's pressure limits across the affected pressure sets, where
+/// largest is defined as the absolute value of the difference. Negative
+/// ExcessUnits indicates a reduction in pressure that had already exceeded the
+/// target's limits.
+///
+/// CriticalMax records the largest increase in the tracker's max pressure that
+/// exceeds the critical limit for some pressure set determined by the client.
+///
+/// CurrentMax records the largest increase in the tracker's max pressure that
+/// exceeds the current limit for some pressure set determined by the client.
+struct RegPressureDelta {
+ PressureElement Excess;
+ PressureElement CriticalMax;
+ PressureElement CurrentMax;
+
+ RegPressureDelta() {}
+};
+
+/// Track the current register pressure at some position in the instruction
+/// stream, and remember the high water mark within the region traversed. This
+/// does not automatically consider live-through ranges. The client may
+/// independently adjust for global liveness.
+///
+/// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
+/// be tracked across a larger region by storing a RegisterPressure result at
+/// each block boundary and explicitly adjusting pressure to account for block
+/// live-in and live-out register sets.
+///
+/// RegPressureTracker holds a reference to a RegisterPressure result that it
+/// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
+/// is invalid until it reaches the end of the block or closeRegion() is
+/// explicitly called. Similarly, P.TopIdx is invalid during upward
+/// tracking. Changing direction has the side effect of closing region, and
+/// traversing past TopIdx or BottomIdx reopens it.
+class RegPressureTracker {
+ const MachineFunction *MF;
+ const TargetRegisterInfo *TRI;
+ const RegisterClassInfo *RCI;
+ const MachineRegisterInfo *MRI;
+ const LiveIntervals *LIS;
+
+ /// We currently only allow pressure tracking within a block.
+ const MachineBasicBlock *MBB;
+
+ /// Track the max pressure within the region traversed so far.
+ RegisterPressure &P;
+
+ /// Run in two modes dependending on whether constructed with IntervalPressure
+ /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
+ bool RequireIntervals;
+
+ /// Register pressure corresponds to liveness before this instruction
+ /// iterator. It may point to the end of the block rather than an instruction.
+ MachineBasicBlock::const_iterator CurrPos;
+
+ /// Pressure map indexed by pressure set ID, not class ID.
+ std::vector<unsigned> CurrSetPressure;
+
+ /// List of live registers.
+ SparseSet<unsigned> LivePhysRegs;
+ SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs;
+
+public:
+ RegPressureTracker(IntervalPressure &rp) :
+ MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true) {}
+
+ RegPressureTracker(RegionPressure &rp) :
+ MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false) {}
+
+ void init(const MachineFunction *mf, const RegisterClassInfo *rci,
+ const LiveIntervals *lis, const MachineBasicBlock *mbb,
+ MachineBasicBlock::const_iterator pos);
+
+ /// Force liveness of registers. Particularly useful to initialize the
+ /// livein/out state of the tracker before the first call to advance/recede.
+ void addLiveRegs(ArrayRef<unsigned> Regs);
+
+ /// Get the MI position corresponding to this register pressure.
+ MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
+
+ // Reset the MI position corresponding to the register pressure. This allows
+ // schedulers to move instructions above the RegPressureTracker's
+ // CurrPos. Since the pressure is computed before CurrPos, the iterator
+ // position changes while pressure does not.
+ void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
+
+ /// Recede across the previous instruction.
+ bool recede();
+
+ /// Advance across the current instruction.
+ bool advance();
+
+ /// Finalize the region boundaries and recored live ins and live outs.
+ void closeRegion();
+
+ /// Get the resulting register pressure over the traversed region.
+ /// This result is complete if either advance() or recede() has returned true,
+ /// or if closeRegion() was explicitly invoked.
+ RegisterPressure &getPressure() { return P; }
+
+ /// Get the register set pressure at the current position, which may be less
+ /// than the pressure across the traversed region.
+ std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
+
+ void discoverPhysLiveIn(unsigned Reg);
+ void discoverPhysLiveOut(unsigned Reg);
+
+ void discoverVirtLiveIn(unsigned Reg);
+ void discoverVirtLiveOut(unsigned Reg);
+
+ bool isTopClosed() const;
+ bool isBottomClosed() const;
+
+ void closeTop();
+ void closeBottom();
+
+ /// Consider the pressure increase caused by traversing this instruction
+ /// bottom-up. Find the pressure set with the most change beyond its pressure
+ /// limit based on the tracker's current pressure, and record the number of
+ /// excess register units of that pressure set introduced by this instruction.
+ void getMaxUpwardPressureDelta(const MachineInstr *MI,
+ RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit);
+
+ /// Consider the pressure increase caused by traversing this instruction
+ /// top-down. Find the pressure set with the most change beyond its pressure
+ /// limit based on the tracker's current pressure, and record the number of
+ /// excess register units of that pressure set introduced by this instruction.
+ void getMaxDownwardPressureDelta(const MachineInstr *MI,
+ RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit);
+
+ /// Find the pressure set with the most change beyond its pressure limit after
+ /// traversing this instruction either upward or downward depending on the
+ /// closed end of the current region.
+ void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit) {
+ if (isTopClosed())
+ return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
+ MaxPressureLimit);
+
+ assert(isBottomClosed() && "Uninitialized pressure tracker");
+ return getMaxUpwardPressureDelta(MI, Delta, CriticalPSets,
+ MaxPressureLimit);
+ }
+
+ /// Get the pressure of each PSet after traversing this instruction bottom-up.
+ void getUpwardPressure(const MachineInstr *MI,
+ std::vector<unsigned> &PressureResult,
+ std::vector<unsigned> &MaxPressureResult);
+
+ /// Get the pressure of each PSet after traversing this instruction top-down.
+ void getDownwardPressure(const MachineInstr *MI,
+ std::vector<unsigned> &PressureResult,
+ std::vector<unsigned> &MaxPressureResult);
+
+ void getPressureAfterInst(const MachineInstr *MI,
+ std::vector<unsigned> &PressureResult,
+ std::vector<unsigned> &MaxPressureResult) {
+ if (isTopClosed())
+ return getUpwardPressure(MI, PressureResult, MaxPressureResult);
+
+ assert(isBottomClosed() && "Uninitialized pressure tracker");
+ return getDownwardPressure(MI, PressureResult, MaxPressureResult);
+ }
+
+protected:
+ void increasePhysRegPressure(ArrayRef<unsigned> Regs);
+ void decreasePhysRegPressure(ArrayRef<unsigned> Regs);
+
+ void increaseVirtRegPressure(ArrayRef<unsigned> Regs);
+ void decreaseVirtRegPressure(ArrayRef<unsigned> Regs);
+
+ void bumpUpwardPressure(const MachineInstr *MI);
+ void bumpDownwardPressure(const MachineInstr *MI);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index f4de6933b317..85ab47beb6b4 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -117,8 +117,9 @@ namespace llvm {
}
}
- bool operator==(const SDep &Other) const {
- if (Dep != Other.Dep || Latency != Other.Latency) return false;
+ /// Return true if the specified SDep is equivalent except for latency.
+ bool overlaps(const SDep &Other) const {
+ if (Dep != Other.Dep) return false;
switch (Dep.getInt()) {
case Data:
case Anti:
@@ -133,6 +134,10 @@ namespace llvm {
llvm_unreachable("Invalid dependency kind!");
}
+ bool operator==(const SDep &Other) const {
+ return overlaps(Other) && Latency == Other.Latency;
+ }
+
bool operator!=(const SDep &Other) const {
return !operator==(Other);
}
@@ -272,6 +277,9 @@ namespace llvm {
unsigned Depth; // Node depth.
unsigned Height; // Node height.
public:
+ unsigned TopReadyCycle; // Cycle relative to start 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 *CopySrcRC;
@@ -287,7 +295,7 @@ namespace llvm {
isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
- CopyDstRC(NULL), CopySrcRC(NULL) {}
+ TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct an SUnit for post-regalloc scheduling to represent
/// a MachineInstr.
@@ -301,7 +309,7 @@ namespace llvm {
isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
- CopyDstRC(NULL), CopySrcRC(NULL) {}
+ TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct a placeholder SUnit.
SUnit()
@@ -314,7 +322,7 @@ namespace llvm {
isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
- CopyDstRC(NULL), CopySrcRC(NULL) {}
+ TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
/// setNode - Assign the representative SDNode for this SUnit.
/// This may be used during pre-regalloc scheduling.
@@ -552,12 +560,6 @@ namespace llvm {
///
virtual void computeLatency(SUnit *SU) = 0;
- /// ComputeOperandLatency - Override dependence edge latency using
- /// operand use/def information
- ///
- virtual void computeOperandLatency(SUnit *, SUnit *,
- SDep&) const { }
-
/// ForceUnitLatencies - Return true if all scheduling edges should be given
/// a latency value of one. The default is to return false; schedulers may
/// override this as needed.
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 4fee108cd2be..1bde94215a57 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -28,6 +28,7 @@ namespace llvm {
class MachineLoopInfo;
class MachineDominatorTree;
class LiveIntervals;
+ class RegPressureTracker;
/// LoopDependencies - This class analyzes loop-oriented register
/// dependencies, which are used to guide scheduling decisions.
@@ -35,7 +36,6 @@ namespace llvm {
/// scheduled as soon as possible after the variable's last use.
///
class LoopDependencies {
- const MachineLoopInfo &MLI;
const MachineDominatorTree &MDT;
public:
@@ -43,9 +43,7 @@ namespace llvm {
LoopDeps;
LoopDeps Deps;
- LoopDependencies(const MachineLoopInfo &mli,
- const MachineDominatorTree &mdt) :
- MLI(mli), MDT(mdt) {}
+ LoopDependencies(const MachineDominatorTree &mdt) : MDT(mdt) {}
/// VisitLoop - Clear out any previous state and analyze the given loop.
///
@@ -105,7 +103,7 @@ namespace llvm {
VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
- unsigned getSparseSetKey() const {
+ unsigned getSparseSetIndex() const {
return TargetRegisterInfo::virtReg2Index(VirtReg);
}
};
@@ -160,7 +158,7 @@ namespace llvm {
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
/// require a destructor.
- typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
+ typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
/// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
/// MachineInstrs.
@@ -229,7 +227,7 @@ namespace llvm {
///
LoopDependencies LoopRegs;
- /// DbgValues - Remember instruction that preceeds DBG_VALUE.
+ /// DbgValues - Remember instruction that precedes DBG_VALUE.
/// These are generated by buildSchedGraph but persist so they can be
/// referenced when emitting the final schedule.
typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
@@ -275,7 +273,7 @@ namespace llvm {
/// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
/// input.
- void buildSchedGraph(AliasAnalysis *AA);
+ void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker = 0);
/// addSchedBarrierDeps - Add dependencies from instructions in the current
/// list of instructions being scheduled to scheduling barrier. We want to
@@ -290,11 +288,15 @@ namespace llvm {
///
virtual void computeLatency(SUnit *SU);
- /// computeOperandLatency - Override dependence edge latency using
+ /// computeOperandLatency - Return dependence edge latency using
/// operand use/def information
///
- virtual void computeOperandLatency(SUnit *Def, SUnit *Use,
- SDep& dep) const;
+ /// FindMin may be set to get the minimum vs. expected latency. Minimum
+ /// latency is used for scheduling groups, while expected latency is for
+ /// instruction cost and critical path.
+ virtual unsigned computeOperandLatency(SUnit *Def, SUnit *Use,
+ const SDep& dep,
+ bool FindMin = false) const;
/// schedule - Order nodes according to selected style, filling
/// in the Sequence member.
@@ -321,10 +323,6 @@ namespace llvm {
void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
-
- VReg2SUnitMap::iterator findVRegDef(unsigned VirtReg) {
- return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
- }
};
/// newSUnit - Creates a new SUnit and return a ptr to it.
diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index 2f53baa1c7e6..9dfa3446ef50 100644
--- a/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -46,6 +46,8 @@ public:
/// atIssueLimit - Return true if no more instructions may be issued in this
/// cycle.
+ ///
+ /// FIXME: remove this once MachineScheduler is the only client.
virtual bool atIssueLimit() const { return false; }
/// getHazardType - Return the hazard type of emitting this node. There are
@@ -55,7 +57,7 @@ public:
/// other instruction is available, issue it first.
/// * NoopHazard: issuing this instruction would break the program. If
/// some other instruction can be issued, do so, otherwise issue a noop.
- virtual HazardType getHazardType(SUnit *m, int Stalls) {
+ virtual HazardType getHazardType(SUnit *m, int Stalls = 0) {
return NoHazard;
}
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 6a7a87e86636..1ccfe54d2126 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -177,6 +177,44 @@ class SelectionDAG {
/// DbgInfo - Tracks dbg_value information through SDISel.
SDDbgInfo *DbgInfo;
+public:
+ /// DAGUpdateListener - Clients of various APIs that cause global effects on
+ /// the DAG can optionally implement this interface. This allows the clients
+ /// to handle the various sorts of updates that happen.
+ ///
+ /// A DAGUpdateListener automatically registers itself with DAG when it is
+ /// constructed, and removes itself when destroyed in RAII fashion.
+ struct DAGUpdateListener {
+ DAGUpdateListener *const Next;
+ SelectionDAG &DAG;
+
+ explicit DAGUpdateListener(SelectionDAG &D)
+ : Next(D.UpdateListeners), DAG(D) {
+ DAG.UpdateListeners = this;
+ }
+
+ virtual ~DAGUpdateListener() {
+ assert(DAG.UpdateListeners == this &&
+ "DAGUpdateListeners must be destroyed in LIFO order");
+ DAG.UpdateListeners = Next;
+ }
+
+ /// NodeDeleted - The node N that was deleted and, if E is not null, an
+ /// equivalent node E that replaced it.
+ virtual void NodeDeleted(SDNode *N, SDNode *E);
+
+ /// NodeUpdated - The node N that was updated.
+ virtual void NodeUpdated(SDNode *N);
+ };
+
+private:
+ /// DAGUpdateListener is a friend so it can manipulate the listener stack.
+ friend struct DAGUpdateListener;
+
+ /// UpdateListeners - Linked list of registered DAGUpdateListener instances.
+ /// This stack is maintained by DAGUpdateListener RAII.
+ DAGUpdateListener *UpdateListeners;
+
/// setGraphColorHelper - Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
///
@@ -384,6 +422,8 @@ public:
int Offset = 0, unsigned char TargetFlags=0) {
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
+ SDValue getTargetIndex(int Index, EVT VT, int64_t Offset = 0,
+ unsigned char TargetFlags = 0);
// When generating a branch to a BB, we don't in general know enough
// to provide debug info for the BB at that time, so keep this one around.
SDValue getBasicBlock(MachineBasicBlock *MBB);
@@ -817,30 +857,14 @@ public:
SDDbgValue *getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
DebugLoc DL, unsigned O);
- /// DAGUpdateListener - Clients of various APIs that cause global effects on
- /// the DAG can optionally implement this interface. This allows the clients
- /// to handle the various sorts of updates that happen.
- class DAGUpdateListener {
- public:
- virtual ~DAGUpdateListener();
-
- /// NodeDeleted - The node N that was deleted and, if E is not null, an
- /// equivalent node E that replaced it.
- virtual void NodeDeleted(SDNode *N, SDNode *E) = 0;
-
- /// NodeUpdated - The node N that was updated.
- virtual void NodeUpdated(SDNode *N) = 0;
- };
-
/// RemoveDeadNode - Remove the specified node from the system. If any of its
/// operands then becomes dead, remove them as well. Inform UpdateListener
/// for each node deleted.
- void RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener = 0);
+ void RemoveDeadNode(SDNode *N);
/// RemoveDeadNodes - This method deletes the unreachable nodes in the
/// given list, and any nodes that become unreachable as a result.
- void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
- DAGUpdateListener *UpdateListener = 0);
+ void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes);
/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG. Use the first
@@ -857,24 +881,19 @@ public:
/// to be given new uses. These new uses of From are left in place, and
/// not automatically transferred to To.
///
- void ReplaceAllUsesWith(SDValue From, SDValue Op,
- DAGUpdateListener *UpdateListener = 0);
- void ReplaceAllUsesWith(SDNode *From, SDNode *To,
- DAGUpdateListener *UpdateListener = 0);
- void ReplaceAllUsesWith(SDNode *From, const SDValue *To,
- DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesWith(SDValue From, SDValue Op);
+ void ReplaceAllUsesWith(SDNode *From, SDNode *To);
+ void ReplaceAllUsesWith(SDNode *From, const SDValue *To);
/// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
/// uses of other values produced by From.Val alone.
- void ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
- DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesOfValueWith(SDValue From, SDValue To);
/// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but
/// for multiple values at once. This correctly handles the case where
/// there is an overlap between the From values and the To values.
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
- unsigned Num,
- DAGUpdateListener *UpdateListener = 0);
+ unsigned Num);
/// AssignTopologicalOrder - Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their
@@ -1031,7 +1050,7 @@ public:
private:
bool RemoveNodeFromCSEMaps(SDNode *N);
- void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
+ void AddModifiedNodeToCSEMaps(SDNode *N);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
void *&InsertPos);
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index ee3f2319c0b3..c42f6558007b 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -172,53 +172,22 @@ protected:
///
unsigned DAGSize;
- /// ISelPosition - Node iterator marking the current position of
- /// instruction selection as it procedes through the topologically-sorted
- /// node list.
- SelectionDAG::allnodes_iterator ISelPosition;
-
-
- /// ISelUpdater - helper class to handle updates of the
- /// instruction selection graph.
- class ISelUpdater : public SelectionDAG::DAGUpdateListener {
- virtual void anchor();
- SelectionDAG::allnodes_iterator &ISelPosition;
- public:
- explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
- : ISelPosition(isp) {}
-
- /// NodeDeleted - Handle nodes deleted from the graph. If the
- /// node being deleted is the current ISelPosition node, update
- /// ISelPosition.
- ///
- virtual void NodeDeleted(SDNode *N, SDNode *E) {
- if (ISelPosition == SelectionDAG::allnodes_iterator(N))
- ++ISelPosition;
- }
-
- /// NodeUpdated - Ignore updates for now.
- virtual void NodeUpdated(SDNode *N) {}
- };
-
/// ReplaceUses - replace all uses of the old node F with the use
/// of the new node T.
void ReplaceUses(SDValue F, SDValue T) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
+ CurDAG->ReplaceAllUsesOfValueWith(F, T);
}
/// ReplaceUses - replace all uses of the old nodes F with the use
/// of the new nodes T.
void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
+ CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num);
}
/// ReplaceUses - replace all uses of the old node F with the use
/// of the new node T.
void ReplaceUses(SDNode *F, SDNode *T) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesWith(F, T, &ISU);
+ CurDAG->ReplaceAllUsesWith(F, T);
}
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index f8248b845337..0dfb394d04a7 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -74,6 +74,10 @@ namespace ISD {
/// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
/// element is not an undef.
bool isScalarToVector(const SDNode *N);
+
+ /// allOperandsUndef - Return true if the node has at least one operand
+ /// and all operands of the specified node are ISD::UNDEF.
+ bool allOperandsUndef(const SDNode *N);
} // end llvm:ISD namespace
//===----------------------------------------------------------------------===//
@@ -1339,6 +1343,29 @@ public:
}
};
+/// Completely target-dependent object reference.
+class TargetIndexSDNode : public SDNode {
+ unsigned char TargetFlags;
+ int Index;
+ int64_t Offset;
+ friend class SelectionDAG;
+public:
+
+ TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned char TF)
+ : SDNode(ISD::TargetIndex, DebugLoc(), getSDVTList(VT)),
+ TargetFlags(TF), Index(Idx), Offset(Ofs) {}
+public:
+
+ unsigned char getTargetFlags() const { return TargetFlags; }
+ int getIndex() const { return Index; }
+ int64_t getOffset() const { return Offset; }
+
+ static bool classof(const TargetIndexSDNode*) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::TargetIndex;
+ }
+};
+
class BasicBlockSDNode : public SDNode {
MachineBasicBlock *MBB;
friend class SelectionDAG;
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 0457e43e6b7b..c52599b0f6f9 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -76,7 +76,6 @@ namespace llvm {
/// SlotIndex - An opaque wrapper around machine indexes.
class SlotIndex {
friend class SlotIndexes;
- friend struct DenseMapInfo<SlotIndex>;
enum Slot {
/// Basic block boundary. Used for live ranges entering and leaving a
@@ -121,11 +120,6 @@ namespace llvm {
return static_cast<Slot>(lie.getInt());
}
- static inline unsigned getHashValue(const SlotIndex &v) {
- void *ptrVal = v.lie.getOpaqueValue();
- return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9);
- }
-
public:
enum {
/// The default distance between instructions as returned by distance().
@@ -133,14 +127,6 @@ namespace llvm {
InstrDist = 4 * Slot_Count
};
- static inline SlotIndex getEmptyKey() {
- return SlotIndex(0, 1);
- }
-
- static inline SlotIndex getTombstoneKey() {
- return SlotIndex(0, 2);
- }
-
/// Construct an invalid index.
SlotIndex() : lie(0, 0) {}
@@ -293,23 +279,6 @@ namespace llvm {
};
- /// DenseMapInfo specialization for SlotIndex.
- template <>
- struct DenseMapInfo<SlotIndex> {
- static inline SlotIndex getEmptyKey() {
- return SlotIndex::getEmptyKey();
- }
- static inline SlotIndex getTombstoneKey() {
- return SlotIndex::getTombstoneKey();
- }
- static inline unsigned getHashValue(const SlotIndex &v) {
- return SlotIndex::getHashValue(v);
- }
- static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
- return (LHS == RHS);
- }
- };
-
template <> struct isPodLike<SlotIndex> { static const bool value = true; };
@@ -344,7 +313,6 @@ namespace llvm {
IndexList indexList;
MachineFunction *mf;
- unsigned functionSize;
typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
Mi2IndexMap mi2iMap;
@@ -402,19 +370,6 @@ namespace llvm {
return SlotIndex(&indexList.back(), 0);
}
- /// Returns the distance between the highest and lowest indexes allocated
- /// so far.
- unsigned getIndexesLength() const {
- assert(indexList.front().getIndex() == 0 &&
- "Initial index isn't zero?");
- return indexList.back().getIndex();
- }
-
- /// Returns the number of instructions in the function.
- unsigned getFunctionSize() const {
- return functionSize;
- }
-
/// Returns true if the given machine instr is mapped to an index,
/// otherwise returns false.
bool hasIndex(const MachineInstr *instr) const {
@@ -444,7 +399,7 @@ namespace llvm {
}
/// getIndexBefore - Returns the index of the last indexed instruction
- /// before MI, or the 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.
SlotIndex getIndexBefore(const MachineInstr *MI) const {
const MachineBasicBlock *MBB = MI->getParent();
@@ -590,7 +545,7 @@ namespace llvm {
nextItr = getIndexAfter(mi).listEntry();
prevItr = prior(nextItr);
} else {
- // Insert mi's index immediately after the preceeding instruction.
+ // Insert mi's index immediately after the preceding instruction.
prevItr = getIndexBefore(mi).listEntry();
nextItr = llvm::next(prevItr);
}
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 5a4213625bae..9849e92f7dec 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -33,6 +33,8 @@ namespace llvm {
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+ bool UseInitArray;
+
public:
virtual ~TargetLoweringObjectFileELF() {}
@@ -66,6 +68,7 @@ public:
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfo *MMI) const;
+ void InitializeELF(bool UseInitArray_);
virtual const MCSection *
getStaticCtorSection(unsigned Priority = 65535) const;
virtual const MCSection *
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index 76c2357a552f..eb38cd33d167 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -68,34 +68,38 @@ namespace llvm {
v2i32 = 22, // 2 x i32
v4i32 = 23, // 4 x i32
v8i32 = 24, // 8 x i32
- v1i64 = 25, // 1 x i64
- v2i64 = 26, // 2 x i64
- v4i64 = 27, // 4 x i64
- v8i64 = 28, // 8 x i64
-
- v2f16 = 29, // 2 x f16
- v2f32 = 30, // 2 x f32
- v4f32 = 31, // 4 x f32
- v8f32 = 32, // 8 x f32
- v2f64 = 33, // 2 x f64
- v4f64 = 34, // 4 x f64
+ v16i32 = 25, // 16 x i32
+ v1i64 = 26, // 1 x i64
+ v2i64 = 27, // 2 x i64
+ v4i64 = 28, // 4 x i64
+ v8i64 = 29, // 8 x i64
+ v16i64 = 30, // 16 x i64
+
+ v2f16 = 31, // 2 x f16
+ v2f32 = 32, // 2 x f32
+ v4f32 = 33, // 4 x f32
+ v8f32 = 34, // 8 x f32
+ v2f64 = 35, // 2 x f64
+ v4f64 = 36, // 4 x f64
FIRST_VECTOR_VALUETYPE = v2i8,
LAST_VECTOR_VALUETYPE = v4f64,
+ FIRST_INTEGER_VECTOR_VALUETYPE = v2i8,
+ LAST_INTEGER_VECTOR_VALUETYPE = v16i64,
FIRST_FP_VECTOR_VALUETYPE = v2f16,
LAST_FP_VECTOR_VALUETYPE = v4f64,
- x86mmx = 35, // This is an X86 MMX value
+ x86mmx = 37, // This is an X86 MMX value
- Glue = 36, // This glues nodes together during pre-RA sched
+ Glue = 38, // This glues nodes together during pre-RA sched
- isVoid = 37, // This has no value
+ isVoid = 39, // This has no value
- Untyped = 38, // This value takes a register, but has
+ Untyped = 40, // This value takes a register, but has
// unspecified type. The register class
// will be determined by the opcode.
- LAST_VALUETYPE = 39, // This always remains at the end of the list.
+ LAST_VALUETYPE = 41, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -153,15 +157,16 @@ namespace llvm {
bool isFloatingPoint() const {
return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
- (SimpleTy >= MVT::FIRST_FP_VECTOR_VALUETYPE &&
- SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE));
+ (SimpleTy >= MVT::FIRST_FP_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE));
}
/// isInteger - Return true if this is an integer, or a vector integer type.
bool isInteger() const {
return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
- (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64));
+ (SimpleTy >= MVT::FIRST_INTEGER_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_INTEGER_VECTOR_VALUETYPE));
}
/// isVector - Return true if this is a vector value type.
@@ -170,6 +175,37 @@ namespace llvm {
SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
}
+ /// is64BitVector - Return true if this is a 64-bit vector type.
+ bool is64BitVector() const {
+ return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 ||
+ SimpleTy == MVT::v2i32 || SimpleTy == MVT::v1i64 ||
+ SimpleTy == MVT::v2f32);
+ }
+
+ /// is128BitVector - Return true if this is a 128-bit vector type.
+ bool is128BitVector() const {
+ return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 ||
+ SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 ||
+ SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
+ }
+
+ /// is256BitVector - Return true if this is a 256-bit vector type.
+ bool is256BitVector() const {
+ return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 ||
+ SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
+ SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64);
+ }
+
+ /// is512BitVector - Return true if this is a 512-bit vector type.
+ bool is512BitVector() const {
+ return (SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
+ }
+
+ /// is1024BitVector - Return true if this is a 1024-bit vector type.
+ bool is1024BitVector() const {
+ return (SimpleTy == MVT::v16i64);
+ }
+
/// isPow2VectorType - Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
unsigned NElts = getVectorNumElements();
@@ -196,7 +232,7 @@ namespace llvm {
MVT getVectorElementType() const {
switch (SimpleTy) {
default:
- return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ llvm_unreachable("Not a vector MVT!");
case v2i8 :
case v4i8 :
case v8i8 :
@@ -208,11 +244,13 @@ namespace llvm {
case v16i16: return i16;
case v2i32:
case v4i32:
- case v8i32: return i32;
+ case v8i32:
+ case v16i32: return i32;
case v1i64:
case v2i64:
case v4i64:
- case v8i64: return i64;
+ case v8i64:
+ case v16i64: return i64;
case v2f16: return f16;
case v2f32:
case v4f32:
@@ -225,10 +263,12 @@ namespace llvm {
unsigned getVectorNumElements() const {
switch (SimpleTy) {
default:
- return ~0U;
+ llvm_unreachable("Not a vector MVT!");
case v32i8: return 32;
case v16i8:
- case v16i16: return 16;
+ case v16i16:
+ case v16i32:
+ case v16i64:return 16;
case v8i8 :
case v8i16:
case v8i32:
@@ -295,7 +335,9 @@ namespace llvm {
case v4i64:
case v8f32:
case v4f64: return 256;
+ case v16i32:
case v8i64: return 512;
+ case v16i64:return 1024;
}
}
@@ -368,12 +410,14 @@ namespace llvm {
if (NumElements == 2) return MVT::v2i32;
if (NumElements == 4) return MVT::v4i32;
if (NumElements == 8) return MVT::v8i32;
+ if (NumElements == 16) return MVT::v16i32;
break;
case MVT::i64:
if (NumElements == 1) return MVT::v1i64;
if (NumElements == 2) return MVT::v2i64;
if (NumElements == 4) return MVT::v4i64;
if (NumElements == 8) return MVT::v8i64;
+ if (NumElements == 16) return MVT::v16i64;
break;
case MVT::f16:
if (NumElements == 2) return MVT::v2f16;
@@ -487,32 +531,27 @@ namespace llvm {
/// is64BitVector - Return true if this is a 64-bit vector type.
bool is64BitVector() const {
- if (!isSimple())
- return isExtended64BitVector();
-
- return (V == MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 ||
- V == MVT::v1i64 || V==MVT::v2f32);
+ return isSimple() ? V.is64BitVector() : isExtended64BitVector();
}
/// is128BitVector - Return true if this is a 128-bit vector type.
bool is128BitVector() const {
- if (!isSimple())
- return isExtended128BitVector();
- return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
- V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64);
+ return isSimple() ? V.is128BitVector() : isExtended128BitVector();
}
/// is256BitVector - Return true if this is a 256-bit vector type.
- inline bool is256BitVector() const {
- if (!isSimple())
- return isExtended256BitVector();
- return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 ||
- V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64);
+ bool is256BitVector() const {
+ return isSimple() ? V.is256BitVector() : isExtended256BitVector();
}
/// is512BitVector - Return true if this is a 512-bit vector type.
- inline bool is512BitVector() const {
- return isSimple() ? (V == MVT::v8i64) : isExtended512BitVector();
+ bool is512BitVector() const {
+ return isSimple() ? V.is512BitVector() : isExtended512BitVector();
+ }
+
+ /// is1024BitVector - Return true if this is a 1024-bit vector type.
+ bool is1024BitVector() const {
+ return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
}
/// isOverloaded - Return true if this is an overloaded type for TableGen.
@@ -705,6 +744,7 @@ namespace llvm {
bool isExtended128BitVector() const;
bool isExtended256BitVector() const;
bool isExtended512BitVector() const;
+ bool isExtended1024BitVector() const;
EVT getExtendedVectorElementType() const;
unsigned getExtendedVectorNumElements() const;
unsigned getExtendedSizeInBits() const;
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
index 6c2269052a11..f4b75bd1b17d 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -45,22 +45,24 @@ def v16i16 : ValueType<256, 21>; // 16 x i16 vector value
def v2i32 : ValueType<64 , 22>; // 2 x i32 vector value
def v4i32 : ValueType<128, 23>; // 4 x i32 vector value
def v8i32 : ValueType<256, 24>; // 8 x i32 vector value
-def v1i64 : ValueType<64 , 25>; // 1 x i64 vector value
-def v2i64 : ValueType<128, 26>; // 2 x i64 vector value
-def v4i64 : ValueType<256, 27>; // 4 x i64 vector value
-def v8i64 : ValueType<512, 28>; // 8 x i64 vector value
+def v16i32 : ValueType<512, 25>; // 16 x i32 vector value
+def v1i64 : ValueType<64 , 26>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 27>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 28>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 29>; // 8 x i64 vector value
+def v16i64 : ValueType<1024,30>; // 16 x i64 vector value
-def v2f16 : ValueType<32 , 29>; // 2 x f16 vector value
-def v2f32 : ValueType<64 , 30>; // 2 x f32 vector value
-def v4f32 : ValueType<128, 31>; // 4 x f32 vector value
-def v8f32 : ValueType<256, 32>; // 8 x f32 vector value
-def v2f64 : ValueType<128, 33>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 34>; // 4 x f64 vector value
+def v2f16 : ValueType<32 , 31>; // 2 x f16 vector value
+def v2f32 : ValueType<64 , 32>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 33>; // 4 x f32 vector value
+def v8f32 : ValueType<256, 34>; // 8 x f32 vector value
+def v2f64 : ValueType<128, 35>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 36>; // 4 x f64 vector value
-def x86mmx : ValueType<64 , 35>; // X86 MMX value
-def FlagVT : ValueType<0 , 36>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 37>; // Produces no value
-def untyped: ValueType<8 , 38>; // Produces an untyped value
+def x86mmx : ValueType<64 , 37>; // X86 MMX value
+def FlagVT : ValueType<0 , 38>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 39>; // Produces no value
+def untyped: ValueType<8 , 40>; // Produces an untyped value
def MetadataVT: ValueType<0, 250>; // Metadata
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 95c4d6cac791..b912251239da 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -14,15 +14,21 @@
/* Directories clang will search for headers */
#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
-/* Define if CBE is enabled for printf %a output */
-#cmakedefine ENABLE_CBE_PRINTF_A ${ENABLE_CBE_PRINTF_A}
+/* Default <path> to all compiler invocations for --sysroot=<path>. */
+#undef DEFAULT_SYSROOT
/* Define if position independent code is enabled */
#cmakedefine ENABLE_PIC
-/* Define if timestamp information (e.g., __DATE___) is allowed */
+/* Define if timestamp information (e.g., __DATE__) is allowed */
#cmakedefine ENABLE_TIMESTAMPS ${ENABLE_TIMESTAMPS}
+/* Directory where gcc is installed. */
+#undef GCC_INSTALL_PREFIX
+
+/* Define to 1 if you have the `arc4random' function. */
+#cmakedefine HAVE_ARC4RANDOM
+
/* Define to 1 if you have the `argz_append' function. */
#cmakedefine HAVE_ARGZ_APPEND ${HAVE_ARGZ_APPEND}
@@ -155,7 +161,7 @@
#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
/* Define if the Graphviz program is available */
-#undef HAVE_GRAPHVIZ
+#cmakedefine HAVE_GRAPHVIZ ${HAVE_GRAPHVIZ}
/* Define if the gv program is available */
#cmakedefine HAVE_GV ${HAVE_GV}
@@ -548,6 +554,9 @@
/* Has gcc/MSVC atomic intrinsics */
#cmakedefine01 LLVM_HAS_ATOMICS
+/* Host triple LLVM will be executed on */
+#cmakedefine LLVM_HOSTTRIPLE "${LLVM_HOSTTRIPLE}"
+
/* Installation directory for include files */
#cmakedefine LLVM_INCLUDEDIR "${LLVM_INCLUDEDIR}"
@@ -617,6 +626,12 @@
/* Installation prefix directory */
#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
+/* Define if we have the Intel JIT API runtime support library */
+#cmakedefine LLVM_USE_INTEL_JITEVENTS 1
+
+/* Define if we have the oprofile JIT-support library */
+#cmakedefine LLVM_USE_OPROFILE 1
+
/* Major version of the LLVM API */
#cmakedefine LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR}
@@ -713,10 +728,4 @@
/* Added by Kevin -- Maximum path length */
#cmakedefine MAXPATHLEN ${MAXPATHLEN}
-/* Support for Intel JIT Events API is enabled */
-#cmakedefine LLVM_USE_INTEL_JITEVENTS 1
-
-/* Support for OProfile JIT API is enabled */
-#cmakedefine LLVM_USE_OPROFILE 1
-
#endif
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 677bf2e40b8d..5a60ba565f00 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -6,6 +6,9 @@
/* Bug report URL. */
#undef BUG_REPORT_URL
+/* Define if we have libxml2 */
+#undef CLANG_HAVE_LIBXML
+
/* Relative directory for resource files */
#undef CLANG_RESOURCE_DIR
@@ -18,12 +21,15 @@
/* Define if position independent code is enabled */
#undef ENABLE_PIC
-/* Define if timestamp information (e.g., __DATE___) is allowed */
+/* Define if timestamp information (e.g., __DATE__) is allowed */
#undef ENABLE_TIMESTAMPS
/* Directory where gcc is installed. */
#undef GCC_INSTALL_PREFIX
+/* Define to 1 if you have the `arc4random' function. */
+#undef HAVE_ARC4RANDOM
+
/* Define to 1 if you have the `argz_append' function. */
#undef HAVE_ARGZ_APPEND
@@ -549,6 +555,9 @@
/* Has gcc/MSVC atomic intrinsics */
#undef LLVM_HAS_ATOMICS
+/* Host triple LLVM will be executed on */
+#undef LLVM_HOSTTRIPLE
+
/* Installation directory for include files */
#undef LLVM_INCLUDEDIR
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 85d28fe134f2..39442926dc9b 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -40,6 +40,9 @@
/* Has gcc/MSVC atomic intrinsics */
#cmakedefine01 LLVM_HAS_ATOMICS
+/* Host triple LLVM will be executed on */
+#cmakedefine LLVM_HOSTTRIPLE "${LLVM_HOSTTRIPLE}"
+
/* Installation directory for include files */
#cmakedefine LLVM_INCLUDEDIR "${LLVM_INCLUDEDIR}"
diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in
index 973652ff2dfb..9489dfe01633 100644
--- a/include/llvm/Config/llvm-config.h.in
+++ b/include/llvm/Config/llvm-config.h.in
@@ -40,6 +40,9 @@
/* Has gcc/MSVC atomic intrinsics */
#undef LLVM_HAS_ATOMICS
+/* Host triple LLVM will be executed on */
+#undef LLVM_HOSTTRIPLE
+
/* Installation directory for include files */
#undef LLVM_INCLUDEDIR
diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h
index 13acdc66b892..e0e516d55c9a 100644
--- a/include/llvm/Constant.h
+++ b/include/llvm/Constant.h
@@ -137,8 +137,8 @@ public:
static Constant *getNullValue(Type* Ty);
- /// @returns the value for an integer constant of the given type that has all
- /// its bits set to true.
+ /// @returns the value for an integer or vector of integer constant of the
+ /// given type that has all its bits set to true.
/// @brief Get the all ones value
static Constant *getAllOnesValue(Type* Ty);
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 0abe17d365d4..fdd53823aa0c 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -917,6 +917,17 @@ public:
return getLShr(C1, C2, true);
}
+ /// getBinOpIdentity - Return the identity for the given binary operation,
+ /// i.e. a constant C such that X op C = X and C op X = X for every X. It
+ /// returns null if the operator doesn't have an identity.
+ static Constant *getBinOpIdentity(unsigned Opcode, Type *Ty);
+
+ /// getBinOpAbsorber - Return the absorbing element for the given binary
+ /// operation, i.e. a constant C such that X op C = C and C op X = C for
+ /// every X. For example, this returns zero for integer multiplication.
+ /// It returns null if the operator doesn't have an absorbing element.
+ static Constant *getBinOpAbsorber(unsigned Opcode, Type *Ty);
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/DIBuilder.h
index 2d109cdbf08f..2ed48a944e96 100644
--- a/include/llvm/Analysis/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -1,4 +1,4 @@
-//===--- llvm/Analysis/DIBuilder.h - Debug Information Builder --*- C++ -*-===//
+//===--- llvm/DIBuilder.h - Debug Information Builder -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -127,8 +127,8 @@ namespace llvm {
StringRef Name = StringRef());
/// createReferenceType - Create debugging information entry for a c++
- /// style reference.
- DIType createReferenceType(DIType RTy);
+ /// style reference or rvalue reference type.
+ DIType createReferenceType(unsigned Tag, DIType RTy);
/// createTypedef - Create debugging information entry for a typedef.
/// @param Ty Original type.
@@ -177,7 +177,7 @@ namespace llvm {
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
- /// @param PropertyName Name of the Objective C property assoicated with
+ /// @param PropertyName Name of the Objective C property associated with
/// this ivar.
/// @param GetterName Name of the Objective C property getter selector.
/// @param SetterName Name of the Objective C property setter selector.
@@ -218,11 +218,11 @@ namespace llvm {
/// @param PropertyAttributes Objective C property attributes.
/// @param Ty Type.
DIObjCProperty createObjCProperty(StringRef Name,
- DIFile File, unsigned LineNumber,
- StringRef GetterName,
- StringRef SetterName,
- unsigned PropertyAttributes,
- DIType Ty);
+ DIFile File, unsigned LineNumber,
+ StringRef GetterName,
+ StringRef SetterName,
+ unsigned PropertyAttributes,
+ DIType Ty);
/// createClassType - Create debugging information entry for a class.
/// @param Scope Scope in which this class is defined.
@@ -329,10 +329,12 @@ namespace llvm {
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param Elements Enumeration elements.
+ /// @param Flags Flags (e.g. forward decl)
DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
DIFile File, unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits, DIArray Elements);
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ DIArray Elements, DIType ClassType,
+ unsigned Flags);
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
@@ -348,8 +350,8 @@ namespace llvm {
DIType createTemporaryType(DIFile F);
/// createForwardDecl - Create a temporary forward-declared type.
- DIType createForwardDecl(unsigned Tag, StringRef Name, DIFile F,
- unsigned Line, unsigned RuntimeLang = 0);
+ DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
+ DIFile F, unsigned Line, unsigned RuntimeLang = 0);
/// retainType - Retain DIType in a module even if it is not referenced
/// through debug info anchors.
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/DebugInfo.h
index 894c5428b988..618220fcb010 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -46,8 +46,8 @@ namespace llvm {
class DIObjCProperty;
/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
- /// This should not be stored in a container, because underly MDNode may
- /// change in certain situations.
+ /// This should not be stored in a container, because the underlying MDNode
+ /// may change in certain situations.
class DIDescriptor {
public:
enum {
@@ -104,12 +104,6 @@ namespace llvm {
return getUnsignedField(0) & ~LLVMDebugVersionMask;
}
- /// print - print descriptor.
- void print(raw_ostream &OS) const;
-
- /// dump - print descriptor to dbgs() with a newline.
- void dump() const;
-
bool isDerivedType() const;
bool isCompositeType() const;
bool isBasicType() const;
@@ -130,10 +124,18 @@ namespace llvm {
bool isTemplateTypeParameter() const;
bool isTemplateValueParameter() const;
bool isObjCProperty() const;
+
+ /// print - print descriptor.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print descriptor to dbgs() with a newline.
+ void dump() const;
};
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
@@ -155,10 +157,11 @@ namespace llvm {
/// DIScope - A base class for various scopes.
class DIScope : public DIDescriptor {
- virtual void anchor();
+ protected:
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
- virtual ~DIScope() {}
StringRef getFilename() const;
StringRef getDirectory() const;
@@ -166,7 +169,8 @@ namespace llvm {
/// DICompileUnit - A wrapper for a compile unit.
class DICompileUnit : public DIScope {
- virtual void anchor();
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
@@ -196,17 +200,12 @@ namespace llvm {
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
-
- /// print - print compile unit.
- void print(raw_ostream &OS) const;
-
- /// dump - print compile unit to dbgs() with a newline.
- void dump() const;
};
/// DIFile - This is a wrapper for a file.
class DIFile : public DIScope {
- virtual void anchor();
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const {} // FIXME: Output something?
public:
explicit DIFile(const MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isFile())
@@ -224,6 +223,8 @@ namespace llvm {
/// FIXME: it seems strange that this doesn't have either a reference to the
/// type/precision or a file/line pair for location info.
class DIEnumerator : public DIDescriptor {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
@@ -235,19 +236,17 @@ namespace llvm {
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
class DIType : public DIScope {
- virtual void anchor();
protected:
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
// This ctor is used when the Tag has already been validated by a derived
// ctor.
DIType(const MDNode *N, bool, bool) : DIScope(N) {}
-
public:
-
/// Verify - Verify that a type descriptor is well formed.
bool Verify() const;
explicit DIType(const MDNode *N);
explicit DIType() {}
- virtual ~DIType() {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
@@ -314,17 +313,10 @@ namespace llvm {
/// this descriptor.
void replaceAllUsesWith(DIDescriptor &D);
void replaceAllUsesWith(MDNode *D);
-
- /// print - print type.
- void print(raw_ostream &OS) const;
-
- /// dump - print type to dbgs() with a newline.
- void dump() const;
};
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
- virtual void anchor();
public:
explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
@@ -332,18 +324,13 @@ namespace llvm {
/// Verify - Verify that a basic type descriptor is well formed.
bool Verify() const;
-
- /// print - print basic type.
- void print(raw_ostream &OS) const;
-
- /// dump - print basic type to dbgs() with a newline.
- void dump() const;
};
/// DIDerivedType - A simple derived type, like a const qualified type,
/// a typedef, a pointer or reference, etc.
class DIDerivedType : public DIType {
- virtual void anchor();
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
protected:
explicit DIDerivedType(const MDNode *N, bool, bool)
: DIType(N, true, true) {}
@@ -401,19 +388,14 @@ namespace llvm {
/// Verify - Verify that a derived type descriptor is well formed.
bool Verify() const;
-
- /// print - print derived type.
- void print(raw_ostream &OS) const;
-
- /// dump - print derived type to dbgs() with a newline.
- void dump() const;
};
/// DICompositeType - This descriptor holds a type that can refer to multiple
/// other types, like a function or struct.
/// FIXME: Why is this a DIDerivedType??
class DICompositeType : public DIDerivedType {
- virtual void anchor();
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DICompositeType(const MDNode *N = 0)
: DIDerivedType(N, true, true) {
@@ -430,12 +412,6 @@ namespace llvm {
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
-
- /// print - print composite type.
- void print(raw_ostream &OS) const;
-
- /// dump - print composite type to dbgs() with a newline.
- void dump() const;
};
/// DITemplateTypeParameter - This is a wrapper for template type parameter.
@@ -477,7 +453,8 @@ namespace llvm {
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
- virtual void anchor();
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
@@ -576,12 +553,6 @@ namespace llvm {
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
- /// print - print subprogram.
- void print(raw_ostream &OS) const;
-
- /// dump - print subprogram to dbgs() with a newline.
- void dump() const;
-
/// describes - Return true if this subprogram provides debugging
/// information for the function F.
bool describes(const Function *F);
@@ -597,6 +568,8 @@ namespace llvm {
/// DIGlobalVariable - This is a wrapper for a global variable.
class DIGlobalVariable : public DIDescriptor {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
@@ -634,17 +607,13 @@ namespace llvm {
/// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const;
-
- /// print - print global variable.
- void print(raw_ostream &OS) const;
-
- /// dump - print global variable to dbgs() with a newline.
- void dump() const;
};
/// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
/// global etc).
class DIVariable : public DIDescriptor {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DIVariable(const MDNode *N = 0)
: DIDescriptor(N) {}
@@ -706,18 +675,11 @@ namespace llvm {
/// information for an inlined function arguments.
bool isInlinedFnArgument(const Function *CurFn);
- /// print - print variable.
- void print(raw_ostream &OS) const;
-
void printExtendedName(raw_ostream &OS) const;
-
- /// dump - print variable to dbgs() with a newline.
- void dump() const;
};
/// DILexicalBlock - This is a wrapper for a lexical block.
class DILexicalBlock : public DIScope {
- virtual void anchor();
public:
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
@@ -736,7 +698,6 @@ namespace llvm {
/// DILexicalBlockFile - This is a wrapper for a lexical block with
/// a filename change.
class DILexicalBlockFile : public DIScope {
- virtual void anchor();
public:
explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getScope().getContext(); }
@@ -756,7 +717,6 @@ namespace llvm {
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
- virtual void anchor();
public:
explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
@@ -794,6 +754,8 @@ namespace llvm {
};
class DIObjCProperty : public DIDescriptor {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
@@ -830,12 +792,6 @@ namespace llvm {
/// Verify - Verify that a derived type descriptor is well formed.
bool Verify() const;
-
- /// print - print derived type.
- void print(raw_ostream &OS) const;
-
- /// dump - print derived type to dbgs() with a newline.
- void dump() const;
};
/// getDISubprogram - Find subprogram that is enclosing this scope.
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index 64f80c506504..cfdeb46889e5 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -15,9 +15,9 @@
#ifndef LLVM_DEBUGINFO_DICONTEXT_H
#define LLVM_DEBUGINFO_DICONTEXT_H
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
-#include <cstring>
namespace llvm {
@@ -25,27 +25,52 @@ class raw_ostream;
/// DILineInfo - a format-neutral container for source line information.
class DILineInfo {
- const char *FileName;
+ SmallString<16> FileName;
+ SmallString<16> FunctionName;
uint32_t Line;
uint32_t Column;
public:
- DILineInfo() : FileName("<invalid>"), Line(0), Column(0) {}
- DILineInfo(const char *fileName, uint32_t line, uint32_t column)
- : FileName(fileName), Line(line), Column(column) {}
+ DILineInfo()
+ : FileName("<invalid>"), FunctionName("<invalid>"),
+ Line(0), Column(0) {}
+ DILineInfo(const SmallString<16> &fileName,
+ const SmallString<16> &functionName,
+ uint32_t line, uint32_t column)
+ : FileName(fileName), FunctionName(functionName),
+ Line(line), Column(column) {}
- const char *getFileName() const { return FileName; }
+ const char *getFileName() { return FileName.c_str(); }
+ const char *getFunctionName() { return FunctionName.c_str(); }
uint32_t getLine() const { return Line; }
uint32_t getColumn() const { return Column; }
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
- std::strcmp(FileName, RHS.FileName) == 0;
+ FileName.equals(RHS.FileName) &&
+ FunctionName.equals(RHS.FunctionName);
}
bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS);
}
};
+/// DILineInfoSpecifier - controls which fields of DILineInfo container
+/// should be filled with data.
+class DILineInfoSpecifier {
+ const uint32_t Flags; // Or'ed flags that set the info we want to fetch.
+public:
+ enum Specification {
+ FileLineInfo = 1 << 0,
+ AbsoluteFilePath = 1 << 1,
+ FunctionName = 1 << 2
+ };
+ // Use file/line info by default.
+ DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {}
+ bool needs(Specification spec) const {
+ return (Flags & spec) > 0;
+ }
+};
+
class DIContext {
public:
virtual ~DIContext();
@@ -60,7 +85,8 @@ public:
virtual void dump(raw_ostream &OS) = 0;
- virtual DILineInfo getLineInfoForAddress(uint64_t address) = 0;
+ virtual DILineInfo getLineInfoForAddress(uint64_t address,
+ DILineInfoSpecifier specifier = DILineInfoSpecifier()) = 0;
};
}
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index e920e98a0bf6..ae8b68d0241e 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -354,7 +354,7 @@ public:
/// variable, possibly emitting it to memory if needed. This is used by the
/// Emitter.
virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
- return getPointerToGlobal((GlobalValue*)GV);
+ return getPointerToGlobal((const GlobalValue *)GV);
}
/// Registers a listener to be called back on various events within
diff --git a/include/llvm/ExecutionEngine/Interpreter.h b/include/llvm/ExecutionEngine/Interpreter.h
index 7425cdbcfda8..72d97ef8e12b 100644
--- a/include/llvm/ExecutionEngine/Interpreter.h
+++ b/include/llvm/ExecutionEngine/Interpreter.h
@@ -23,7 +23,7 @@ extern "C" void LLVMLinkInInterpreter();
namespace {
struct ForceInterpreterLinking {
ForceInterpreterLinking() {
- // We must reference the passes in such a way that compilers will not
+ // We must reference the interpreter in such a way that compilers will not
// delete it all as dead code, even with whole program optimization,
// 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.
diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h
index 6013db48ce69..b4cda1d513f1 100644
--- a/include/llvm/ExecutionEngine/JIT.h
+++ b/include/llvm/ExecutionEngine/JIT.h
@@ -23,7 +23,7 @@ extern "C" void LLVMLinkInJIT();
namespace {
struct ForceJITLinking {
ForceJITLinking() {
- // We must reference the passes in such a way that compilers will not
+ // We must reference JIT in such a way that compilers will not
// delete it all as dead code, even with whole program optimization,
// 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.
diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h
index f956a5029b17..ac16bdc7df17 100644
--- a/include/llvm/ExecutionEngine/MCJIT.h
+++ b/include/llvm/ExecutionEngine/MCJIT.h
@@ -23,7 +23,7 @@ extern "C" void LLVMLinkInMCJIT();
namespace {
struct ForceMCJITLinking {
ForceMCJITLinking() {
- // We must reference the passes in such a way that compilers will not
+ // We must reference MCJIT in such a way that compilers will not
// delete it all as dead code, even with whole program optimization,
// 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.
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index 54c28f3ec142..a5c9272d3ca6 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -65,12 +65,15 @@ public:
RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld();
+ /// Load an in-memory object file into the dynamic linker.
bool loadObject(MemoryBuffer *InputBuffer);
- // 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
- // and resolve relocatons based on where they put it).
+
+ /// 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
+ /// and resolve relocatons based on where they put it).
void *getSymbolAddress(StringRef Name);
- // Resolve the relocations for all symbols we currently know about.
+
+ /// Resolve the relocations for all symbols we currently know about.
void resolveRelocations();
/// mapSectionAddress - map a section to its target address space value.
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
index e17cd87fe348..fdd90d1d8faa 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/Function.h
@@ -420,8 +420,8 @@ public:
void dropAllReferences();
/// hasAddressTaken - returns true if there are any uses of this function
- /// other than direct calls or invokes to it. Optionally passes back the
- /// offending user for diagnostic purposes.
+ /// other than direct calls or invokes to it, or blockaddress expressions.
+ /// Optionally passes back an offending user for diagnostic purposes.
///
bool hasAddressTaken(const User** = 0) const;
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index 81a11a4c9258..8b969f3354c3 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -164,6 +164,12 @@ public:
return Linkage == CommonLinkage;
}
+ /// isDiscardableIfUnused - Whether the definition of this global may be
+ /// discarded if it is not used in its compilation unit.
+ static bool isDiscardableIfUnused(LinkageTypes Linkage) {
+ return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage);
+ }
+
/// mayBeOverridden - Whether the definition of this global may be replaced
/// by something non-equivalent at link time. For example, if a function has
/// weak linkage then the code defining it may be replaced by different code.
@@ -221,6 +227,10 @@ public:
void setLinkage(LinkageTypes LT) { Linkage = LT; }
LinkageTypes getLinkage() const { return Linkage; }
+ bool isDiscardableIfUnused() const {
+ return isDiscardableIfUnused(Linkage);
+ }
+
bool mayBeOverridden() const { return mayBeOverridden(Linkage); }
bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h
index 034ade1fb031..99b7a73b35ac 100644
--- a/include/llvm/GlobalVariable.h
+++ b/include/llvm/GlobalVariable.h
@@ -41,24 +41,35 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
void setParent(Module *parent);
bool isConstantGlobal : 1; // Is this a global constant?
- bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"?
+ unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
+ // if so, what is the desired model?
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
return User::operator new(s, 1);
}
+
+ enum ThreadLocalMode {
+ NotThreadLocal = 0,
+ GeneralDynamicTLSModel,
+ LocalDynamicTLSModel,
+ InitialExecTLSModel,
+ LocalExecTLSModel
+ };
+
/// GlobalVariable ctor - If a parent module is specified, the global is
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = 0, const Twine &Name = "",
- bool ThreadLocal = false, unsigned AddressSpace = 0);
+ ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
GlobalVariable(Module &M, Type *Ty, bool isConstant,
LinkageTypes Linkage, Constant *Initializer,
- const Twine &Name,
- GlobalVariable *InsertBefore = 0, bool ThreadLocal = false,
+ const Twine &Name = "",
+ GlobalVariable *InsertBefore = 0,
+ ThreadLocalMode = NotThreadLocal,
unsigned AddressSpace = 0);
~GlobalVariable() {
@@ -135,8 +146,14 @@ public:
void setConstant(bool Val) { isConstantGlobal = Val; }
/// If the value is "Thread Local", its value isn't shared by the threads.
- bool isThreadLocal() const { return isThreadLocalSymbol; }
- void setThreadLocal(bool Val) { isThreadLocalSymbol = Val; }
+ bool isThreadLocal() const { return threadLocalMode != NotThreadLocal; }
+ void setThreadLocal(bool Val) {
+ threadLocalMode = Val ? GeneralDynamicTLSModel : NotThreadLocal;
+ }
+ void setThreadLocalMode(ThreadLocalMode Val) { threadLocalMode = Val; }
+ ThreadLocalMode getThreadLocalMode() const {
+ return static_cast<ThreadLocalMode>(threadLocalMode);
+ }
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/IRBuilder.h
index ef00e8ec24ed..d5b6f47f8a25 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/IRBuilder.h
@@ -1,4 +1,4 @@
-//===---- llvm/Support/IRBuilder.h - Builder for LLVM Instrs ----*- C++ -*-===//
+//===---- llvm/IRBuilder.h - Builder for LLVM Instructions ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_IRBUILDER_H
-#define LLVM_SUPPORT_IRBUILDER_H
+#ifndef LLVM_IRBUILDER_H
+#define LLVM_IRBUILDER_H
#include "llvm/Instructions.h"
#include "llvm/BasicBlock.h"
@@ -411,6 +411,17 @@ public:
// Instruction creation methods: Terminators
//===--------------------------------------------------------------------===//
+private:
+ /// \brief Helper to add branch weight metadata onto an instruction.
+ /// \returns The annotated instruction.
+ template <typename InstTy>
+ InstTy *addBranchWeights(InstTy *I, MDNode *Weights) {
+ if (Weights)
+ I->setMetadata(LLVMContext::MD_prof, Weights);
+ return I;
+ }
+
+public:
/// CreateRetVoid - Create a 'ret void' instruction.
ReturnInst *CreateRetVoid() {
return Insert(ReturnInst::Create(Context));
@@ -444,15 +455,19 @@ public:
/// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
/// instruction.
- BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
- return Insert(BranchInst::Create(True, False, Cond));
+ BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False,
+ MDNode *BranchWeights = 0) {
+ return Insert(addBranchWeights(BranchInst::Create(True, False, Cond),
+ BranchWeights));
}
/// CreateSwitch - Create a switch instruction with the specified value,
/// default dest, and with a hint for the number of cases that will be added
/// (for efficient allocation).
- SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
- return Insert(SwitchInst::Create(V, Dest, NumCases));
+ SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10,
+ MDNode *BranchWeights = 0) {
+ return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases),
+ BranchWeights));
}
/// CreateIndirectBr - Create an indirect branch instruction with the
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 33d20435de1d..de97957a84c6 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -71,6 +71,7 @@ void initializeBasicCallGraphPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);
void initializeBlockPlacementPass(PassRegistry&);
+void initializeBoundsCheckingPass(PassRegistry&);
void initializeBranchFolderPassPass(PassRegistry&);
void initializeBranchProbabilityInfoPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
@@ -99,6 +100,7 @@ void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierPass(PassRegistry&);
void initializeDominatorTreePass(PassRegistry&);
+void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeEdgeProfilerPass(PassRegistry&);
void initializeExpandPostRAPass(PassRegistry&);
@@ -135,6 +137,7 @@ void initializeLibCallAliasAnalysisPass(PassRegistry&);
void initializeLintPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveRegMatrixPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&);
void initializeLiveVariablesPass(PassRegistry&);
void initializeLoaderPassPass(PassRegistry&);
@@ -169,6 +172,7 @@ void initializeMachineLoopRangesPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
void initializeMachineSchedulerPass(PassRegistry&);
void initializeMachineSinkingPass(PassRegistry&);
+void initializeMachineTraceMetricsPass(PassRegistry&);
void initializeMachineVerifierPassPass(PassRegistry&);
void initializeMemCpyOptPass(PassRegistry&);
void initializeMemDepPrinterPass(PassRegistry&);
@@ -214,7 +218,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&);
void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&);
void initializeRegionViewerPass(PassRegistry&);
-void initializeRenderMachineFunctionPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&);
void initializeSROA_DTPass(PassRegistry&);
void initializeSROA_SSAUpPass(PassRegistry&);
@@ -247,10 +250,12 @@ void initializeUnreachableBlockElimPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
void initializeVerifierPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
+void initializeVirtRegRewriterPass(PassRegistry&);
void initializeInstSimplifierPass(PassRegistry&);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeFinalizeMachineBundlesPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
+void initializeMachineFunctionPrinterPassPass(PassRegistry&);
}
#endif
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h
index 9c5ac4430f89..5512dcc9e6b6 100644
--- a/include/llvm/Instruction.h
+++ b/include/llvm/Instruction.h
@@ -215,6 +215,27 @@ public:
bool isCommutative() const { return isCommutative(getOpcode()); }
static bool isCommutative(unsigned op);
+ /// isIdempotent - Return true if the instruction is idempotent:
+ ///
+ /// Idempotent operators satisfy: x op x === x
+ ///
+ /// In LLVM, the And and Or operators are idempotent.
+ ///
+ bool isIdempotent() const { return isIdempotent(getOpcode()); }
+ static bool isIdempotent(unsigned op);
+
+ /// isNilpotent - Return true if the instruction is nilpotent:
+ ///
+ /// Nilpotent operators satisfy: x op x === Id,
+ ///
+ /// where Id is the identity for the operator, i.e. a constant such that
+ /// x op Id === x and Id op x === x for all x.
+ ///
+ /// In LLVM, the Xor operator is nilpotent.
+ ///
+ bool isNilpotent() const { return isNilpotent(getOpcode()); }
+ static bool isNilpotent(unsigned op);
+
/// mayWriteToMemory - Return true if this instruction may modify memory.
///
bool mayWriteToMemory() const;
@@ -260,6 +281,16 @@ public:
/// ignores the SubclassOptionalData flags, which specify conditions
/// under which the instruction's result is undefined.
bool isIdenticalToWhenDefined(const Instruction *I) const;
+
+ /// When checking for operation equivalence (using isSameOperationAs) it is
+ /// sometimes useful to ignore certain attributes.
+ enum OperationEquivalenceFlags {
+ /// Check for equivalence ignoring load/store alignment.
+ CompareIgnoringAlignment = 1<<0,
+ /// Check for equivalence treating a type and a vector of that type
+ /// as equivalent.
+ CompareUsingScalarTypes = 1<<1
+ };
/// This function determines if the specified instruction executes the same
/// operation as the current one. This means that the opcodes, type, operand
@@ -269,7 +300,7 @@ public:
/// @returns true if the specified instruction is the same operation as
/// the current one.
/// @brief Determine if one instruction is the same operation as another.
- bool isSameOperationAs(const Instruction *I) const;
+ bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const;
/// isUsedOutsideOfBlock - Return true if there are any uses of this
/// instruction in blocks other than the specified block. Note that PHI nodes
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index f6eaf04fd0d9..f5187e683269 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -20,6 +20,8 @@
#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/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
@@ -699,7 +701,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value)
// checkGEPType - Simple wrapper function to give a better assertion failure
// message on bad indexes for a gep instruction.
//
-static inline Type *checkGEPType(Type *Ty) {
+inline Type *checkGEPType(Type *Ty) {
assert(Ty && "Invalid GetElementPtrInst indices for type!");
return Ty;
}
@@ -1265,6 +1267,11 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attributes attr);
+ /// \brief Return true if this call has the given attribute.
+ bool hasFnAttr(Attributes N) const {
+ return paramHasAttr(~0, N);
+ }
+
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(unsigned i, Attributes attr) const;
@@ -1274,7 +1281,7 @@ public:
}
/// @brief Return true if the call should not be inlined.
- bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline(bool Value = true) {
if (Value) addAttribute(~0, Attribute::NoInline);
else removeAttribute(~0, Attribute::NoInline);
@@ -1282,7 +1289,7 @@ public:
/// @brief Return true if the call can return twice
bool canReturnTwice() const {
- return paramHasAttr(~0, Attribute::ReturnsTwice);
+ return hasFnAttr(Attribute::ReturnsTwice);
}
void setCanReturnTwice(bool Value = true) {
if (Value) addAttribute(~0, Attribute::ReturnsTwice);
@@ -1291,7 +1298,7 @@ public:
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
- return paramHasAttr(~0, Attribute::ReadNone);
+ return hasFnAttr(Attribute::ReadNone);
}
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
@@ -1300,7 +1307,7 @@ public:
/// @brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
+ return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
@@ -1308,14 +1315,14 @@ public:
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
+ bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
+ bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
@@ -2237,7 +2244,7 @@ public:
/// getNumClauses - Get the number of clauses for this landing pad.
unsigned getNumClauses() const { return getNumOperands() - 1; }
- /// reserveClauses - Grow the size of the operand list to accomodate the new
+ /// reserveClauses - Grow the size of the operand list to accommodate the new
/// number of clauses.
void reserveClauses(unsigned Size) { growOperands(Size); }
@@ -2440,10 +2447,31 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
class SwitchInst : public TerminatorInst {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
unsigned ReservedSpace;
+ // Operands format:
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
// Operand[2n ] = Value to match
// Operand[2n+1] = BasicBlock to go to on match
+
+ // Store case values separately from operands list. We needn't User-Use
+ // concept here, since it is just a case value, it will always constant,
+ // and case value couldn't reused with another instructions/values.
+ // Additionally:
+ // It allows us to use custom type for case values that is not inherited
+ // from Value. Since case value is a complex type that implements
+ // the subset of integers, we needn't extract sub-constants within
+ // slow getAggregateElement method.
+ // For case values we will use std::list to by two reasons:
+ // 1. It allows to add/remove cases without whole collection reallocation.
+ // 2. In most of cases we needn't random access.
+ // Currently case values are also stored in Operands List, but it will moved
+ // out in future commits.
+ typedef std::list<IntegersSubset> Subsets;
+ typedef Subsets::iterator SubsetsIt;
+ typedef Subsets::const_iterator SubsetsConstIt;
+
+ Subsets TheSubsets;
+
SwitchInst(const SwitchInst &SI);
void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
void growOperands();
@@ -2468,121 +2496,25 @@ protected:
virtual SwitchInst *clone_impl() const;
public:
+ // FIXME: Currently there are a lot of unclean template parameters,
+ // we need to make refactoring in future.
+ // All these parameters are used to implement both iterator and const_iterator
+ // without code duplication.
+ // SwitchInstTy may be "const SwitchInst" or "SwitchInst"
+ // ConstantIntTy may be "const ConstantInt" or "ConstantInt"
+ // SubsetsItTy may be SubsetsConstIt or SubsetsIt
+ // BasicBlockTy may be "const BasicBlock" or "BasicBlock"
+ template <class SwitchInstTy, class ConstantIntTy,
+ class SubsetsItTy, class BasicBlockTy>
+ class CaseIteratorT;
+
+ typedef CaseIteratorT<const SwitchInst, const ConstantInt,
+ SubsetsConstIt, const BasicBlock> ConstCaseIt;
+ class CaseIt;
+
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
- template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
- class CaseIteratorT {
- protected:
-
- SwitchInstTy *SI;
- unsigned Index;
-
- public:
-
- typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
-
- /// Initializes case iterator for given SwitchInst and for given
- /// case number.
- CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
- this->SI = SI;
- Index = CaseNum;
- }
-
- /// Initializes case iterator for given SwitchInst and for given
- /// TerminatorInst's successor index.
- static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
- assert(SuccessorIndex < SI->getNumSuccessors() &&
- "Successor index # out of range!");
- return SuccessorIndex != 0 ?
- Self(SI, SuccessorIndex - 1) :
- Self(SI, DefaultPseudoIndex);
- }
-
- /// Resolves case value for current case.
- ConstantIntTy *getCaseValue() {
- assert(Index < SI->getNumCases() && "Index out the number of cases.");
- return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
- }
-
- /// Resolves successor for current case.
- BasicBlockTy *getCaseSuccessor() {
- assert((Index < SI->getNumCases() ||
- Index == DefaultPseudoIndex) &&
- "Index out the number of cases.");
- return SI->getSuccessor(getSuccessorIndex());
- }
-
- /// Returns number of current case.
- unsigned getCaseIndex() const { return Index; }
-
- /// Returns TerminatorInst's successor index for current case successor.
- unsigned getSuccessorIndex() const {
- assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
- "Index out the number of cases.");
- return Index != DefaultPseudoIndex ? Index + 1 : 0;
- }
-
- Self operator++() {
- // Check index correctness after increment.
- // Note: Index == getNumCases() means end().
- assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
- ++Index;
- return *this;
- }
- Self operator++(int) {
- Self tmp = *this;
- ++(*this);
- return tmp;
- }
- Self operator--() {
- // Check index correctness after decrement.
- // Note: Index == getNumCases() means end().
- // Also allow "-1" iterator here. That will became valid after ++.
- assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
- "Index out the number of cases.");
- --Index;
- return *this;
- }
- Self operator--(int) {
- Self tmp = *this;
- --(*this);
- return tmp;
- }
- bool operator==(const Self& RHS) const {
- assert(RHS.SI == SI && "Incompatible operators.");
- return RHS.Index == Index;
- }
- bool operator!=(const Self& RHS) const {
- assert(RHS.SI == SI && "Incompatible operators.");
- return RHS.Index != Index;
- }
- };
-
- typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
- ConstCaseIt;
-
- class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
-
- typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
-
- public:
-
- CaseIt(const ParentTy& Src) : ParentTy(Src) {}
- CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
-
- /// Sets the new value for current case.
- void setValue(ConstantInt *V) {
- assert(Index < SI->getNumCases() && "Index out the number of cases.");
- SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
- }
-
- /// Sets the new successor for current case.
- void setSuccessor(BasicBlock *S) {
- SI->setSuccessor(getSuccessorIndex(), S);
- }
- };
-
static SwitchInst *Create(Value *Value, BasicBlock *Default,
unsigned NumCases, Instruction *InsertBefore = 0) {
return new SwitchInst(Value, Default, NumCases, InsertBefore);
@@ -2618,23 +2550,23 @@ public:
/// Returns a read/write iterator that points to the first
/// case in SwitchInst.
CaseIt case_begin() {
- return CaseIt(this, 0);
+ return CaseIt(this, 0, TheSubsets.begin());
}
/// Returns a read-only iterator that points to the first
/// case in the SwitchInst.
ConstCaseIt case_begin() const {
- return ConstCaseIt(this, 0);
+ return ConstCaseIt(this, 0, TheSubsets.begin());
}
/// Returns a read/write iterator that points one past the last
/// in the SwitchInst.
CaseIt case_end() {
- return CaseIt(this, getNumCases());
+ return CaseIt(this, getNumCases(), TheSubsets.end());
}
/// Returns a read-only iterator that points one past the last
/// in the SwitchInst.
ConstCaseIt case_end() const {
- return ConstCaseIt(this, getNumCases());
+ return ConstCaseIt(this, getNumCases(), TheSubsets.end());
}
/// Returns an iterator that points to the default case.
/// Note: this iterator allows to resolve successor only. Attempt
@@ -2642,10 +2574,10 @@ public:
/// Also note, that increment and decrement also causes an assertion and
/// makes iterator invalid.
CaseIt case_default() {
- return CaseIt(this, DefaultPseudoIndex);
+ return CaseIt(this, DefaultPseudoIndex, TheSubsets.end());
}
ConstCaseIt case_default() const {
- return ConstCaseIt(this, DefaultPseudoIndex);
+ return ConstCaseIt(this, DefaultPseudoIndex, TheSubsets.end());
}
/// findCaseValue - Search all of the case values for the specified constant.
@@ -2654,13 +2586,13 @@ public:
/// that it is handled by the default handler.
CaseIt findCaseValue(const ConstantInt *C) {
for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
+ if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
return i;
return case_default();
}
ConstCaseIt findCaseValue(const ConstantInt *C) const {
for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
+ if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
return i;
return case_default();
}
@@ -2681,10 +2613,17 @@ public:
}
/// addCase - Add an entry to the switch instruction...
+ /// @Deprecated
/// Note:
/// This action invalidates case_end(). Old case_end() iterator will
/// point to the added case.
void addCase(ConstantInt *OnVal, BasicBlock *Dest);
+
+ /// addCase - Add an entry to the switch instruction.
+ /// Note:
+ /// This action invalidates case_end(). Old case_end() iterator will
+ /// point to the added case.
+ void addCase(IntegersSubset& OnVal, BasicBlock *Dest);
/// removeCase - This method removes the specified case and its successor
/// from the switch instruction. Note that this operation may reorder the
@@ -2692,7 +2631,7 @@ public:
/// Note:
/// This action invalidates iterators for all cases following the one removed,
/// including the case_end() iterator.
- void removeCase(CaseIt i);
+ void removeCase(CaseIt& i);
unsigned getNumSuccessors() const { return getNumOperands()/2; }
BasicBlock *getSuccessor(unsigned idx) const {
@@ -2703,8 +2642,193 @@ public:
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
setOperand(idx*2+1, (Value*)NewSucc);
}
+
+ uint16_t hash() const {
+ uint32_t NumberOfCases = (uint32_t)getNumCases();
+ uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
+ for (ConstCaseIt i = case_begin(), e = case_end();
+ i != e; ++i) {
+ uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
+ Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
+ }
+ return Hash;
+ }
+
+ // Case iterators definition.
+
+ template <class SwitchInstTy, class ConstantIntTy,
+ class SubsetsItTy, class BasicBlockTy>
+ class CaseIteratorT {
+ protected:
+
+ SwitchInstTy *SI;
+ unsigned long Index;
+ SubsetsItTy SubsetIt;
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// case number.
+ friend class SwitchInst;
+ CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex,
+ SubsetsItTy CaseValueIt) {
+ this->SI = SI;
+ Index = SuccessorIndex;
+ this->SubsetIt = CaseValueIt;
+ }
+
+ public:
+ typedef typename SubsetsItTy::reference IntegersSubsetRef;
+ typedef CaseIteratorT<SwitchInstTy, ConstantIntTy,
+ SubsetsItTy, BasicBlockTy> Self;
+
+ CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
+ this->SI = SI;
+ Index = CaseNum;
+ SubsetIt = SI->TheSubsets.begin();
+ std::advance(SubsetIt, CaseNum);
+ }
+
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// TerminatorInst's successor index.
+ static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
+ assert(SuccessorIndex < SI->getNumSuccessors() &&
+ "Successor index # out of range!");
+ return SuccessorIndex != 0 ?
+ Self(SI, SuccessorIndex - 1) :
+ Self(SI, DefaultPseudoIndex);
+ }
+
+ /// Resolves case value for current case.
+ /// @Deprecated
+ ConstantIntTy *getCaseValue() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ IntegersSubsetRef CaseRanges = *SubsetIt;
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So return CaseValue as ConstantInt.
+ return CaseRanges.getSingleNumber(0).toConstantInt();
+ }
+
+ /// Resolves case value for current case.
+ IntegersSubsetRef getCaseValueEx() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ return *SubsetIt;
+ }
+
+ /// Resolves successor for current case.
+ BasicBlockTy *getCaseSuccessor() {
+ assert((Index < SI->getNumCases() ||
+ Index == DefaultPseudoIndex) &&
+ "Index out the number of cases.");
+ return SI->getSuccessor(getSuccessorIndex());
+ }
+
+ /// Returns number of current case.
+ unsigned getCaseIndex() const { return Index; }
+
+ /// Returns TerminatorInst's successor index for current case successor.
+ unsigned getSuccessorIndex() const {
+ assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
+ "Index out the number of cases.");
+ return Index != DefaultPseudoIndex ? Index + 1 : 0;
+ }
+
+ Self operator++() {
+ // Check index correctness after increment.
+ // Note: Index == getNumCases() means end().
+ assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
+ ++Index;
+ if (Index == 0)
+ SubsetIt = SI->TheSubsets.begin();
+ else
+ ++SubsetIt;
+ return *this;
+ }
+ Self operator++(int) {
+ Self tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+ Self operator--() {
+ // Check index correctness after decrement.
+ // Note: Index == getNumCases() means end().
+ // Also allow "-1" iterator here. That will became valid after ++.
+ unsigned NumCases = SI->getNumCases();
+ assert((Index == 0 || Index-1 <= NumCases) &&
+ "Index out the number of cases.");
+ --Index;
+ if (Index == NumCases) {
+ SubsetIt = SI->TheSubsets.end();
+ return *this;
+ }
+
+ if (Index != -1UL)
+ --SubsetIt;
+
+ return *this;
+ }
+ Self operator--(int) {
+ Self tmp = *this;
+ --(*this);
+ return tmp;
+ }
+ bool operator==(const Self& RHS) const {
+ assert(RHS.SI == SI && "Incompatible operators.");
+ return RHS.Index == Index;
+ }
+ bool operator!=(const Self& RHS) const {
+ assert(RHS.SI == SI && "Incompatible operators.");
+ return RHS.Index != Index;
+ }
+ };
+
+ class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt,
+ SubsetsIt, BasicBlock> {
+ typedef CaseIteratorT<SwitchInst, ConstantInt, SubsetsIt, BasicBlock>
+ ParentTy;
+
+ protected:
+ friend class SwitchInst;
+ CaseIt(SwitchInst *SI, unsigned CaseNum, SubsetsIt SubsetIt) :
+ ParentTy(SI, CaseNum, SubsetIt) {}
+
+ void updateCaseValueOperand(IntegersSubset& V) {
+ SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V));
+ }
+
+ public:
+
+ CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+
+ CaseIt(const ParentTy& Src) : ParentTy(Src) {}
+
+ /// Sets the new value for current case.
+ /// @Deprecated.
+ void setValue(ConstantInt *V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ IntegersSubsetToBB Mapping;
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ Mapping.add(IntItem::fromConstantInt(V));
+ *SubsetIt = Mapping.getCase();
+ updateCaseValueOperand(*SubsetIt);
+ }
+
+ /// Sets the new value for current case.
+ void setValueEx(IntegersSubset& V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ *SubsetIt = V;
+ updateCaseValueOperand(*SubsetIt);
+ }
+
+ /// Sets the new successor for current case.
+ void setSuccessor(BasicBlock *S) {
+ SI->setSuccessor(getSuccessorIndex(), S);
+ }
+ };
// Methods for support type inquiry through isa, cast, and dyn_cast:
+
static inline bool classof(const SwitchInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Switch;
@@ -2905,6 +3029,11 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attributes attr);
+ /// \brief Return true if this call has the given attribute.
+ bool hasFnAttr(Attributes N) const {
+ return paramHasAttr(~0, N);
+ }
+
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(unsigned i, Attributes attr) const;
@@ -2914,7 +3043,7 @@ public:
}
/// @brief Return true if the call should not be inlined.
- bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline(bool Value = true) {
if (Value) addAttribute(~0, Attribute::NoInline);
else removeAttribute(~0, Attribute::NoInline);
@@ -2922,7 +3051,7 @@ public:
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
- return paramHasAttr(~0, Attribute::ReadNone);
+ return hasFnAttr(Attribute::ReadNone);
}
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
@@ -2931,7 +3060,7 @@ public:
/// @brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
+ return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
@@ -2939,14 +3068,14 @@ public:
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
+ bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
+ bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h
index 370382560337..c3503889e702 100644
--- a/include/llvm/Intrinsics.h
+++ b/include/llvm/Intrinsics.h
@@ -74,6 +74,53 @@ namespace Intrinsic {
/// Map a GCC builtin name to an intrinsic ID.
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
+ /// IITDescriptor - This is a type descriptor which explains the type
+ /// requirements of an intrinsic. This is returned by
+ /// getIntrinsicInfoTableEntries.
+ struct IITDescriptor {
+ enum IITDescriptorKind {
+ Void, MMX, Metadata, Float, Double,
+ Integer, Vector, Pointer, Struct,
+ Argument, ExtendVecArgument, TruncVecArgument
+ } Kind;
+
+ union {
+ unsigned Integer_Width;
+ unsigned Float_Width;
+ unsigned Vector_Width;
+ unsigned Pointer_AddressSpace;
+ unsigned Struct_NumElements;
+ unsigned Argument_Info;
+ };
+
+ enum ArgKind {
+ AK_AnyInteger,
+ AK_AnyFloat,
+ AK_AnyVector,
+ AK_AnyPointer
+ };
+ unsigned getArgumentNumber() const {
+ assert(Kind == Argument || Kind == ExtendVecArgument ||
+ Kind == TruncVecArgument);
+ return Argument_Info >> 2;
+ }
+ ArgKind getArgumentKind() const {
+ assert(Kind == Argument || Kind == ExtendVecArgument ||
+ Kind == TruncVecArgument);
+ return (ArgKind)(Argument_Info&3);
+ }
+
+ static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
+ IITDescriptor Result = { K, { Field } };
+ return Result;
+ }
+ };
+
+ /// getIntrinsicInfoTableEntries - Return the IIT table descriptor for the
+ /// specified intrinsic into an array of IITDescriptors.
+ ///
+ void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
+
} // End Intrinsic namespace
} // End llvm namespace
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 069f907d4ff2..d1a0feef1d5a 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -55,6 +55,8 @@ class NoCapture<int argNo> : IntrinsicProperty {
int ArgNo = argNo;
}
+def IntrNoReturn : IntrinsicProperty;
+
//===----------------------------------------------------------------------===//
// Types used by intrinsics.
//===----------------------------------------------------------------------===//
@@ -63,11 +65,15 @@ class LLVMType<ValueType vt> {
ValueType VT = vt;
}
-class LLVMPointerType<LLVMType elty>
+class LLVMQualPointerType<LLVMType elty, int addrspace>
: LLVMType<iPTR>{
LLVMType ElTy = elty;
+ int AddrSpace = addrspace;
}
+class LLVMPointerType<LLVMType elty>
+ : LLVMQualPointerType<elty, 0>;
+
class LLVMAnyPointerType<LLVMType elty>
: LLVMType<iPTRAny>{
LLVMType ElTy = elty;
@@ -127,9 +133,12 @@ def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16
def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32
def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32
def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32
+def llvm_v16i32_ty : LLVMType<v16i32>; // 16 x i32
def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64
def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64
def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64
+def llvm_v8i64_ty : LLVMType<v8i64>; // 8 x i64
+def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float
@@ -155,10 +164,11 @@ def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
// intrinsic.
// * Properties can be set to describe the behavior of the intrinsic.
//
+class SDPatternOperator;
class Intrinsic<list<LLVMType> ret_types,
list<LLVMType> param_types = [],
list<IntrinsicProperty> properties = [],
- string name = ""> {
+ string name = ""> : SDPatternOperator {
string LLVMName = name;
string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
list<LLVMType> RetTypes = ret_types;
@@ -253,12 +263,18 @@ let Properties = [IntrReadMem] in {
def int_log2 : 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_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
}
let Properties = [IntrNoMem] in {
def int_fma : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
+
+ def int_fmuladd : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>]>;
}
// NOTE: these are internal interfaces.
@@ -297,7 +313,7 @@ let Properties = [IntrNoMem] in {
let Properties = [IntrNoMem] in {
def int_dbg_declare : Intrinsic<[],
[llvm_metadata_ty, llvm_metadata_ty]>;
- def int_dbg_value : Intrinsic<[],
+ def int_dbg_value : Intrinsic<[],
[llvm_metadata_ty, llvm_i64_ty,
llvm_metadata_ty]>;
}
@@ -396,8 +412,13 @@ def int_invariant_end : Intrinsic<[],
//
def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
GCCBuiltin<"__builtin_flt_rounds">;
-def int_trap : Intrinsic<[]>,
+def int_trap : Intrinsic<[], [], [IntrNoReturn]>,
GCCBuiltin<"__builtin_trap">;
+def int_debugtrap : Intrinsic<[]>,
+ GCCBuiltin<"__builtin_debugtrap">;
+
+// NOP: calls/invokes to this intrinsic are removed by codegen
+def int_donothing : Intrinsic<[], [], [IntrNoMem]>;
// Intrisics to support half precision floating point format
let Properties = [IntrNoMem] in {
@@ -439,5 +460,6 @@ include "llvm/IntrinsicsX86.td"
include "llvm/IntrinsicsARM.td"
include "llvm/IntrinsicsCellSPU.td"
include "llvm/IntrinsicsXCore.td"
-include "llvm/IntrinsicsPTX.td"
include "llvm/IntrinsicsHexagon.td"
+include "llvm/IntrinsicsNVVM.td"
+include "llvm/IntrinsicsMips.td"
diff --git a/include/llvm/IntrinsicsHexagon.td b/include/llvm/IntrinsicsHexagon.td
index eb5dc8fb1e7f..efd04f309ae3 100644
--- a/include/llvm/IntrinsicsHexagon.td
+++ b/include/llvm/IntrinsicsHexagon.td
@@ -225,6 +225,22 @@ class Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
[llvm_i1_ty], [llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
//
+// DEF_FUNCTION_TYPE_2(QI_ftype_SIDI,BT_BOOL,BT_INT,BT_LONGLONG) ->
+// Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sidi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_DISI,BT_BOOL,BT_LONGLONG,BT_INT) ->
+// Hexagon_qi_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_disi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
// DEF_FUNCTION_TYPE_2(QI_ftype_QIQI,BT_BOOL,BT_BOOL,BT_BOOL) ->
// Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
//
@@ -406,3266 +422,4456 @@ class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
+class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+//
+// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_di_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_sf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_di_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_si_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_si_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_df_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_sfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_float_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_qi_sfqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_float_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_sfsfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsfsf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty, llvm_float_ty,
+ llvm_float_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty, llvm_float_ty,
+ llvm_float_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_dididisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_di_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_di_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_df_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_df_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_dfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_double_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+//
+// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty, llvm_double_ty,
+ llvm_double_ty],
+ [IntrNoMem]>;
+//
+// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty, llvm_double_ty,
+ llvm_double_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+
+
+// This one below will not be generated from iset.py.
+// So make sure, you don't overwrite this one.
+//
+// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
+//
+def int_hexagon_SI_to_SXTHI_asrh :
+Hexagon_si_si_Intrinsic<"SI_to_SXTHI_asrh">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldd :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldd">;
+// This one above will not be generated from iset.py.
+// So make sure, you don't overwrite this one.
//
// BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpeq : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpeq">;
+def int_hexagon_C2_cmpeq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeq">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgt,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgt : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgt">;
+def int_hexagon_C2_cmpgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgt">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtu,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgtu : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgtu">;
+def int_hexagon_C2_cmpgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtu">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpeqp,QI_ftype_DIDI,2)
//
-def int_hexagon_C2_cmpeqp : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpeqp">;
+def int_hexagon_C2_cmpeqp :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpeqp">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtp,QI_ftype_DIDI,2)
//
-def int_hexagon_C2_cmpgtp : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpgtp">;
+def int_hexagon_C2_cmpgtp :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtp">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtup,QI_ftype_DIDI,2)
//
-def int_hexagon_C2_cmpgtup : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpgtup">;
+def int_hexagon_C2_cmpgtup :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtup">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpneq">;
//
// BUILTIN_INFO(HEXAGON.C2_bitsset,QI_ftype_SISI,2)
//
-def int_hexagon_C2_bitsset : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsset">;
+def int_hexagon_C2_bitsset :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsset">;
//
// BUILTIN_INFO(HEXAGON.C2_bitsclr,QI_ftype_SISI,2)
//
-def int_hexagon_C2_bitsclr : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsclr">;
+def int_hexagon_C2_bitsclr :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclr">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsset,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsset :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsset">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsclr,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsclr :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclr">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpeqi,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpeqi : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpeqi">;
+def int_hexagon_C2_cmpeqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeqi">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgti,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgti : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgti">;
+def int_hexagon_C2_cmpgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgti">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtui,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgtui : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgtui">;
+def int_hexagon_C2_cmpgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtui">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgei,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgei : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgei">;
+def int_hexagon_C2_cmpgei :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgei">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgeui,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpgeui : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgeui">;
+def int_hexagon_C2_cmpgeui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgeui">;
//
// BUILTIN_INFO(HEXAGON.C2_cmplt,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmplt : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmplt">;
+def int_hexagon_C2_cmplt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmplt">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpltu,QI_ftype_SISI,2)
//
-def int_hexagon_C2_cmpltu : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpltu">;
+def int_hexagon_C2_cmpltu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpltu">;
//
// BUILTIN_INFO(HEXAGON.C2_bitsclri,QI_ftype_SISI,2)
//
-def int_hexagon_C2_bitsclri : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsclri">;
+def int_hexagon_C2_bitsclri :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclri">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsclri,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsclri :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclri">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneqi,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpltei,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpltei :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpltei">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteui,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteui">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneq,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneq">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplte,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplte :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplte">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteu,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteu">;
//
// BUILTIN_INFO(HEXAGON.C2_and,QI_ftype_QIQI,2)
//
-def int_hexagon_C2_and : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.and">;
+def int_hexagon_C2_and :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_and">;
//
// BUILTIN_INFO(HEXAGON.C2_or,QI_ftype_QIQI,2)
//
-def int_hexagon_C2_or : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.or">;
+def int_hexagon_C2_or :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_or">;
//
// BUILTIN_INFO(HEXAGON.C2_xor,QI_ftype_QIQI,2)
//
-def int_hexagon_C2_xor : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.xor">;
+def int_hexagon_C2_xor :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_xor">;
//
// BUILTIN_INFO(HEXAGON.C2_andn,QI_ftype_QIQI,2)
//
-def int_hexagon_C2_andn : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.andn">;
+def int_hexagon_C2_andn :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_andn">;
//
// BUILTIN_INFO(HEXAGON.C2_not,QI_ftype_QI,1)
//
-def int_hexagon_C2_not : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.not">;
+def int_hexagon_C2_not :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_not">;
//
// BUILTIN_INFO(HEXAGON.C2_orn,QI_ftype_QIQI,2)
//
-def int_hexagon_C2_orn : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.orn">;
+def int_hexagon_C2_orn :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_or">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_or">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_orn">;
//
// BUILTIN_INFO(HEXAGON.C2_pxfer_map,QI_ftype_QI,1)
//
-def int_hexagon_C2_pxfer_map : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.pxfer.map">;
+def int_hexagon_C2_pxfer_map :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_pxfer_map">;
//
// BUILTIN_INFO(HEXAGON.C2_any8,QI_ftype_QI,1)
//
-def int_hexagon_C2_any8 : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.any8">;
+def int_hexagon_C2_any8 :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_any8">;
//
// BUILTIN_INFO(HEXAGON.C2_all8,QI_ftype_QI,1)
//
-def int_hexagon_C2_all8 : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.all8">;
+def int_hexagon_C2_all8 :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_all8">;
//
// BUILTIN_INFO(HEXAGON.C2_vitpack,SI_ftype_QIQI,2)
//
-def int_hexagon_C2_vitpack : Hexagon_si_qiqi_Intrinsic<"HEXAGON.C2.vitpack">;
+def int_hexagon_C2_vitpack :
+Hexagon_si_qiqi_Intrinsic<"HEXAGON_C2_vitpack">;
//
// BUILTIN_INFO(HEXAGON.C2_mux,SI_ftype_QISISI,3)
//
-def int_hexagon_C2_mux : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.mux">;
+def int_hexagon_C2_mux :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_mux">;
//
// BUILTIN_INFO(HEXAGON.C2_muxii,SI_ftype_QISISI,3)
//
-def int_hexagon_C2_muxii : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxii">;
+def int_hexagon_C2_muxii :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxii">;
//
// BUILTIN_INFO(HEXAGON.C2_muxir,SI_ftype_QISISI,3)
//
-def int_hexagon_C2_muxir : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxir">;
+def int_hexagon_C2_muxir :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxir">;
//
// BUILTIN_INFO(HEXAGON.C2_muxri,SI_ftype_QISISI,3)
//
-def int_hexagon_C2_muxri : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxri">;
+def int_hexagon_C2_muxri :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxri">;
//
// BUILTIN_INFO(HEXAGON.C2_vmux,DI_ftype_QIDIDI,3)
//
-def int_hexagon_C2_vmux : Hexagon_di_qididi_Intrinsic<"HEXAGON.C2.vmux">;
+def int_hexagon_C2_vmux :
+Hexagon_di_qididi_Intrinsic<"HEXAGON_C2_vmux">;
//
// BUILTIN_INFO(HEXAGON.C2_mask,DI_ftype_QI,1)
//
-def int_hexagon_C2_mask : Hexagon_di_qi_Intrinsic<"HEXAGON.C2.mask">;
+def int_hexagon_C2_mask :
+Hexagon_di_qi_Intrinsic<"HEXAGON_C2_mask">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpbeq,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpbeq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpbeq">;
+def int_hexagon_A2_vcmpbeq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbeqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbeqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbeq_any,QI_ftype_DIDI,2)
+//
+def int_hexagon_A4_vcmpbeq_any :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpbgtu,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpbgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpbgtu">;
+def int_hexagon_A2_vcmpbgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A4_vcmpbgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbeq,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbeq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbeqi,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbeqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgt,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgti,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgti">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpheq,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpheq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpheq">;
+def int_hexagon_A2_vcmpheq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpheq">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmphgt,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmphgt : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmphgt">;
+def int_hexagon_A2_vcmphgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgt">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmphgtu,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmphgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmphgtu">;
+def int_hexagon_A2_vcmphgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpheqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpheqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpheqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmphgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmphgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmphgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmphgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpheq,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpheq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgt,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpheqi,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpheqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgti,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtui">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpweq,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpweq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpweq">;
+def int_hexagon_A2_vcmpweq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpweq">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpwgt,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpwgt : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpwgt">;
+def int_hexagon_A2_vcmpwgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgt">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpwgtu,QI_ftype_DIDI,2)
//
-def int_hexagon_A2_vcmpwgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpwgtu">;
+def int_hexagon_A2_vcmpwgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpweqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpweqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpweqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpwgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpwgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpwgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpwgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_boundscheck,QI_ftype_SIDI,2)
+//
+def int_hexagon_A4_boundscheck :
+Hexagon_qi_sidi_Intrinsic<"HEXAGON_A4_boundscheck">;
+//
+// BUILTIN_INFO(HEXAGON.A4_tlbmatch,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_tlbmatch :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_tlbmatch">;
//
// BUILTIN_INFO(HEXAGON.C2_tfrpr,SI_ftype_QI,1)
//
-def int_hexagon_C2_tfrpr : Hexagon_si_qi_Intrinsic<"HEXAGON.C2.tfrpr">;
+def int_hexagon_C2_tfrpr :
+Hexagon_si_qi_Intrinsic<"HEXAGON_C2_tfrpr">;
//
// BUILTIN_INFO(HEXAGON.C2_tfrrp,QI_ftype_SI,1)
//
-def int_hexagon_C2_tfrrp : Hexagon_qi_si_Intrinsic<"HEXAGON.C2.tfrrp">;
+def int_hexagon_C2_tfrrp :
+Hexagon_qi_si_Intrinsic<"HEXAGON_C2_tfrrp">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9 :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9_not,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9_not :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_acc_sat_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpy_nac_sat_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_hh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_hh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_hl_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hl.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_hl_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hl.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_lh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.lh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_lh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.lh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_ll_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.ll.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_ll_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.ll.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_hh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_hh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_hl_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hl.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_hl_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hl.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_lh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.lh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_lh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.lh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_ll_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.ll.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_ll_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.ll.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_hh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_hh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_hl_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hl.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_hl_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hl.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_lh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.lh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_lh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.lh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_ll_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.ll.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_rnd_ll_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.ll.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_hh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_hh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_hl_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hl.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_hl_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hl.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_lh_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.lh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_lh_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.lh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_ll_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.ll.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_sat_rnd_ll_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.ll.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_hh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_hh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_hl_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hl.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_hl_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hl.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_lh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.lh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_lh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.lh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_ll_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.ll.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_acc_ll_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.ll.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_hh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_hh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_hl_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hl.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_hl_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hl.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_lh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.lh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_lh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.lh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_ll_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.ll.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyd_nac_ll_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.ll.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_hh_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_hh_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_hl_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hl.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_hl_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hl.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_lh_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.lh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_lh_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.lh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_ll_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.ll.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_ll_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.ll.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_hh_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_hh_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_hl_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hl.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_hl_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hl.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_lh_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.lh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_lh_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.lh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_ll_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.ll.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_mpyd_rnd_ll_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.ll.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_acc_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_hh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_hh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_hl_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hl.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_hl_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hl.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_lh_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.lh.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_lh_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.lh.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s0,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_ll_s0 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.ll.s0">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s1,SI_ftype_SISISI,3)
//
def int_hexagon_M2_mpyu_nac_ll_s1 :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.ll.s1">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s0,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_hh_s0 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s1,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_hh_s1 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s0,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_hl_s0 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hl.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s1,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_hl_s1 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hl.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s0,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_lh_s0 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.lh.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s1,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_lh_s1 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.lh.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s0,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_ll_s0 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.ll.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s1,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_ll_s1 :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.ll.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_hh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_hh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_hl_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hl.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_hl_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hl.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_lh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.lh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_lh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.lh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_ll_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.ll.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_acc_ll_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.ll.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_hh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_hh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_hl_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hl.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_hl_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hl.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_lh_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.lh.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_lh_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.lh.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_ll_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.ll.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_mpyud_nac_ll_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.ll.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s0,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_hh_s0 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s1,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_hh_s1 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s0,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_hl_s0 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hl.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s1,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_hl_s1 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hl.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s0,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_lh_s0 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.lh.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_lh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s1,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_lh_s1 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.lh.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_lh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s0,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_ll_s0 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.ll.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_ll_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s1,UDI_ftype_SISI,2)
//
def int_hexagon_M2_mpyud_ll_s1 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.ll.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_ll_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mpysmi,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpysmi :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpysmi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpysmi">;
//
// BUILTIN_INFO(HEXAGON.M2_macsip,SI_ftype_SISISI,3)
//
def int_hexagon_M2_macsip :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.macsip">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_macsip">;
//
// BUILTIN_INFO(HEXAGON.M2_macsin,SI_ftype_SISISI,3)
//
def int_hexagon_M2_macsin :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.macsin">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_macsin">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyss_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_dpmpyss_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.dpmpyss.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_dpmpyss_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyss_acc_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_dpmpyss_acc_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyss.acc.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyss_acc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyss_nac_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_dpmpyss_nac_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyss.nac.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyss_nac_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_s0,UDI_ftype_SISI,2)
//
def int_hexagon_M2_dpmpyuu_s0 :
-Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.dpmpyuu.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_dpmpyuu_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_acc_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_dpmpyuu_acc_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyuu.acc.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyuu_acc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_nac_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_dpmpyuu_nac_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyuu.nac.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyuu_nac_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_up,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpy_up :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.up">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up_s1_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up_s1_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up_s1_sat">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyu_up,USI_ftype_SISI,2)
//
def int_hexagon_M2_mpyu_up :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.up">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpysu_up,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpysu_up :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpysu_up">;
//
// BUILTIN_INFO(HEXAGON.M2_dpmpyss_rnd_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_dpmpyss_rnd_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.dpmpyss.rnd.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_dpmpyss_rnd_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mac_up_s1_sat,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mac_up_s1_sat :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mac_up_s1_sat">;
+//
+// BUILTIN_INFO(HEXAGON.M4_nac_up_s1_sat,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_nac_up_s1_sat :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_nac_up_s1_sat">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyi,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpyi :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpyi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyi">;
//
// BUILTIN_INFO(HEXAGON.M2_mpyui,SI_ftype_SISI,2)
//
def int_hexagon_M2_mpyui :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpyui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyui">;
//
// BUILTIN_INFO(HEXAGON.M2_maci,SI_ftype_SISISI,3)
//
def int_hexagon_M2_maci :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.maci">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_maci">;
//
// BUILTIN_INFO(HEXAGON.M2_acci,SI_ftype_SISISI,3)
//
def int_hexagon_M2_acci :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.acci">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_acci">;
//
// BUILTIN_INFO(HEXAGON.M2_accii,SI_ftype_SISISI,3)
//
def int_hexagon_M2_accii :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.accii">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_accii">;
//
// BUILTIN_INFO(HEXAGON.M2_nacci,SI_ftype_SISISI,3)
//
def int_hexagon_M2_nacci :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.nacci">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_nacci">;
//
// BUILTIN_INFO(HEXAGON.M2_naccii,SI_ftype_SISISI,3)
//
def int_hexagon_M2_naccii :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.naccii">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_naccii">;
//
// BUILTIN_INFO(HEXAGON.M2_subacc,SI_ftype_SISISI,3)
//
def int_hexagon_M2_subacc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.subacc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_subacc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyrr_addr,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyrr_addr :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyrr_addr">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addr_u2,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addr_u2 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addr_u2">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addr,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addr :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addr">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addi,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addi">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyrr_addi,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyrr_addi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyrr_addi">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_vmpy2s_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_vmpy2s_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2s_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_vmac2s_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2s.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2s_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2s_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_vmac2s_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2s.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2s_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2su_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2su_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2su_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2su_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2su_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2su_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2su_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2su_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2su_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2su_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2su_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2su_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0pack,SI_ftype_SISI,2)
//
def int_hexagon_M2_vmpy2s_s0pack :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s0pack">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s0pack">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1pack,SI_ftype_SISI,2)
//
def int_hexagon_M2_vmpy2s_s1pack :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s1pack">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s1pack">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2,DI_ftype_DISISI,3)
//
def int_hexagon_M2_vmac2 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vmpy2es_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vmpy2es.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vmpy2es_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vmpy2es_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vmpy2es.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vmpy2es_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2es_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vmac2es_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2es_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vmac2es_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vmac2es,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vmac2es :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es">;
//
// BUILTIN_INFO(HEXAGON.M2_vrmac_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vrmac_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrmac.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrmac_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrmpy_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vrmpy_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrmpy.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrmpy_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s0,SI_ftype_DIDI,2)
//
def int_hexagon_M2_vdmpyrs_s0 :
-Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vdmpyrs.s0">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vdmpyrs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s1,SI_ftype_DIDI,2)
//
def int_hexagon_M2_vdmpyrs_s1 :
-Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vdmpyrs.s1">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vdmpyrs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmpybuu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vrmpybuu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vrmpybuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmacbuu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vrmacbuu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vrmacbuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmpybsu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vrmpybsu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vrmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmacbsu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vrmacbsu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vrmacbsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmpybuu,DI_ftype_SISI,2)
+//
+def int_hexagon_M5_vmpybuu :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M5_vmpybuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmpybsu,DI_ftype_SISI,2)
+//
+def int_hexagon_M5_vmpybsu :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M5_vmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmacbuu,DI_ftype_DISISI,3)
+//
+def int_hexagon_M5_vmacbuu :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M5_vmacbuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmacbsu,DI_ftype_DISISI,3)
+//
+def int_hexagon_M5_vmacbsu :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M5_vmacbsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vdmpybsu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vdmpybsu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vdmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vdmacbsu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vdmacbsu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vdmacbsu">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmacs_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vdmacs_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vdmacs.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vdmacs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmacs_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vdmacs_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vdmacs.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vdmacs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmpys_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vdmpys_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vdmpys.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vdmpys_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vdmpys_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vdmpys_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vdmpys.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vdmpys_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyrs_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrs.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyrs_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrs.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s0,SI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyrsc_s0 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrsc.s0">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrsc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s1,SI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyrsc_s1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrsc.s1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrsc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmacs_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmacs_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacs.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmacs_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmacs_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacs.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmacsc_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmacsc_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacsc.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacsc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmacsc_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmacsc_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacsc.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacsc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpys_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpys_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpys.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpys_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpys_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpys_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpys.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpys_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpysc_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpysc_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpysc.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpysc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpysc_s1,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpysc_s1 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpysc.s1">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpysc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cnacs_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cnacs_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacs.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cnacs_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cnacs_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacs.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_cnacsc_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cnacsc_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacsc.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacsc_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cnacsc_s1,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cnacsc_s1 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacsc.s1">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacsc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1,DI_ftype_DISI,2)
//
def int_hexagon_M2_vrcmpys_s1 :
-Hexagon_di_disi_Intrinsic<"HEXAGON.M2.vrcmpys.s1">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_M2_vrcmpys_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpys_acc_s1,DI_ftype_DIDISI,3)
//
def int_hexagon_M2_vrcmpys_acc_s1 :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.M2.vrcmpys.acc.s1">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_M2_vrcmpys_acc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1rp,SI_ftype_DISI,2)
//
def int_hexagon_M2_vrcmpys_s1rp :
-Hexagon_si_disi_Intrinsic<"HEXAGON.M2.vrcmpys.s1rp">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_M2_vrcmpys_s1rp">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacls_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacls_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacls_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacls_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmachs_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmachs_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmachs_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmachs_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyl_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyl_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyl_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyl_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyh_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyh_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyh_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyh_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacls_rs0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacls_rs0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.rs0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacls_rs1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacls_rs1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.rs1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmachs_rs0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmachs_rs0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.rs0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmachs_rs1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmachs_rs1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.rs1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyl_rs0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.rs0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyl_rs1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.rs1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyh_rs0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.rs0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyh_rs1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.rs1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyeh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyeh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyeh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyeh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_acc_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyeh_acc_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_acc_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyeh_acc_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyoh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyoh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyoh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyoh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_acc_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyoh_acc_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_acc_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyoh_acc_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_hmmpyl_rs1,SI_ftype_SISI,2)
//
def int_hexagon_M2_hmmpyl_rs1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.hmmpyl.rs1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyl_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_hmmpyh_rs1,SI_ftype_SISI,2)
//
def int_hexagon_M2_hmmpyh_rs1 :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.hmmpyh.rs1">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyh_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmaculs_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmaculs_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmaculs_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmaculs_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacuhs_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacuhs_s1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.s1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyul_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyul_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyul_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyul_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyuh_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyuh_s1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.s1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_s1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmaculs_rs0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.rs0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmaculs_rs1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.rs1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacuhs_rs0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.rs0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs1,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_mmacuhs_rs1 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.rs1">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyul_rs0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.rs0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyul_rs1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.rs1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyuh_rs0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.rs0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_rs0">;
//
// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs1,DI_ftype_DIDI,2)
//
def int_hexagon_M2_mmpyuh_rs1 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.rs1">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_rs1">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vrcmaci_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmaci.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmaci_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vrcmacr_s0 :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmacr.s0">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmacr_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0c,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vrcmaci_s0c :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmaci.s0c">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmaci_s0c">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0c,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vrcmacr_s0c :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmacr.s0c">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmacr_s0c">;
//
// BUILTIN_INFO(HEXAGON.M2_cmaci_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmaci_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmaci.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmaci_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmacr_s0,DI_ftype_DISISI,3)
//
def int_hexagon_M2_cmacr_s0 :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacr.s0">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacr_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vrcmpyi_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyi.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyi_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vrcmpyr_s0 :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyr.s0">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyr_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0c,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vrcmpyi_s0c :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyi.s0c">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyi_s0c">;
//
// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0c,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vrcmpyr_s0c :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyr.s0c">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyr_s0c">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyi_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyi_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpyi.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpyi_s0">;
//
// BUILTIN_INFO(HEXAGON.M2_cmpyr_s0,DI_ftype_SISI,2)
//
def int_hexagon_M2_cmpyr_s0 :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpyr.s0">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpyr_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyi_wh,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyi_wh :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyi_wh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyr_wh,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyr_wh :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyr_wh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyi_whc,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyi_whc :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyi_whc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyr_whc,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyr_whc :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyr_whc">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_i,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vcmpy_s0_sat_i :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s0.sat.i">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_i">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_r,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vcmpy_s0_sat_r :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s0.sat.r">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_r">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_i,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vcmpy_s1_sat_i :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s1.sat.i">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_i">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_r,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vcmpy_s1_sat_r :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s1.sat.r">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_r">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_i,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vcmac_s0_sat_i :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vcmac.s0.sat.i">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_i">;
//
// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_r,DI_ftype_DIDIDI,3)
//
def int_hexagon_M2_vcmac_s0_sat_r :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vcmac.s0.sat.r">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_r">;
//
// BUILTIN_INFO(HEXAGON.S2_vcrotate,DI_ftype_DISI,2)
//
def int_hexagon_S2_vcrotate :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.vcrotate">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_vcrotate">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vrcrotate_acc,DI_ftype_DIDISISI,4)
+//
+def int_hexagon_S4_vrcrotate_acc :
+Hexagon_di_didisisi_Intrinsic<"HEXAGON_S4_vrcrotate_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vrcrotate,DI_ftype_DISISI,3)
+//
+def int_hexagon_S4_vrcrotate :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S4_vrcrotate">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vcnegh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_vcnegh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_vcnegh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrcnegh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_vrcnegh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_vrcnegh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_pmpyw,DI_ftype_SISI,2)
+//
+def int_hexagon_M4_pmpyw :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M4_pmpyw">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vpmpyh,DI_ftype_SISI,2)
+//
+def int_hexagon_M4_vpmpyh :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M4_vpmpyh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_pmpyw_acc,DI_ftype_DISISI,3)
+//
+def int_hexagon_M4_pmpyw_acc :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M4_pmpyw_acc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vpmpyh_acc,DI_ftype_DISISI,3)
+//
+def int_hexagon_M4_vpmpyh_acc :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M4_vpmpyh_acc">;
//
// BUILTIN_INFO(HEXAGON.A2_add,SI_ftype_SISI,2)
//
def int_hexagon_A2_add :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.add">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_add">;
//
// BUILTIN_INFO(HEXAGON.A2_sub,SI_ftype_SISI,2)
//
def int_hexagon_A2_sub :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.sub">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_sub">;
//
// BUILTIN_INFO(HEXAGON.A2_addsat,SI_ftype_SISI,2)
//
def int_hexagon_A2_addsat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addsat">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addsat">;
//
// BUILTIN_INFO(HEXAGON.A2_subsat,SI_ftype_SISI,2)
//
def int_hexagon_A2_subsat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subsat">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subsat">;
//
// BUILTIN_INFO(HEXAGON.A2_addi,SI_ftype_SISI,2)
//
def int_hexagon_A2_addi :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addi">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_l16_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_l16_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_l16_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_l16_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.hl">;
-def int_hexagon_A2_addh_l16_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.lh">;
-def int_hexagon_A2_addh_l16_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_l16_sat_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_sat_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_l16_sat_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.hl">;
-def int_hexagon_A2_addh_l16_sat_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.lh">;
-def int_hexagon_A2_addh_l16_sat_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_sat_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_l16_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_l16_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_l16_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_l16_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_l16_sat_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.sat.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_sat_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_l16_sat_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.sat.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_sat_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_lh,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.lh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_lh">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_hh,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_hh">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_sat_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_lh,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_sat_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.lh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_lh">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_sat_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hh,SI_ftype_SISI,2)
//
def int_hexagon_A2_addh_h16_sat_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_hh">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_lh,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.lh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_lh">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_hh,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_hh">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_sat_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_lh,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_sat_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.lh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_lh">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_sat_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hh,SI_ftype_SISI,2)
//
def int_hexagon_A2_subh_h16_sat_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_hh">;
//
// BUILTIN_INFO(HEXAGON.A2_aslh,SI_ftype_SI,1)
//
def int_hexagon_A2_aslh :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.aslh">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_aslh">;
//
// BUILTIN_INFO(HEXAGON.A2_asrh,SI_ftype_SI,1)
//
def int_hexagon_A2_asrh :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.asrh">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_asrh">;
//
// BUILTIN_INFO(HEXAGON.A2_addp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_addp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.addp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_addp">;
//
// BUILTIN_INFO(HEXAGON.A2_addpsat,DI_ftype_DIDI,2)
//
def int_hexagon_A2_addpsat :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.addpsat">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_addpsat">;
//
// BUILTIN_INFO(HEXAGON.A2_addsp,DI_ftype_SIDI,2)
//
def int_hexagon_A2_addsp :
-Hexagon_di_sidi_Intrinsic<"HEXAGON.A2.addsp">;
+Hexagon_di_sidi_Intrinsic<"HEXAGON_A2_addsp">;
//
// BUILTIN_INFO(HEXAGON.A2_subp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_subp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.subp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_subp">;
//
// BUILTIN_INFO(HEXAGON.A2_neg,SI_ftype_SI,1)
//
def int_hexagon_A2_neg :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.neg">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_neg">;
//
// BUILTIN_INFO(HEXAGON.A2_negsat,SI_ftype_SI,1)
//
def int_hexagon_A2_negsat :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.negsat">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_negsat">;
//
// BUILTIN_INFO(HEXAGON.A2_abs,SI_ftype_SI,1)
//
def int_hexagon_A2_abs :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.abs">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_abs">;
//
// BUILTIN_INFO(HEXAGON.A2_abssat,SI_ftype_SI,1)
//
def int_hexagon_A2_abssat :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.abssat">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_abssat">;
//
// BUILTIN_INFO(HEXAGON.A2_vconj,DI_ftype_DI,1)
//
def int_hexagon_A2_vconj :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.vconj">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vconj">;
//
// BUILTIN_INFO(HEXAGON.A2_negp,DI_ftype_DI,1)
//
def int_hexagon_A2_negp :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.negp">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_negp">;
//
// BUILTIN_INFO(HEXAGON.A2_absp,DI_ftype_DI,1)
//
def int_hexagon_A2_absp :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.absp">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_absp">;
//
// BUILTIN_INFO(HEXAGON.A2_max,SI_ftype_SISI,2)
//
def int_hexagon_A2_max :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.max">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_max">;
//
// BUILTIN_INFO(HEXAGON.A2_maxu,USI_ftype_SISI,2)
//
def int_hexagon_A2_maxu :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.A2.maxu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_maxu">;
//
// BUILTIN_INFO(HEXAGON.A2_min,SI_ftype_SISI,2)
//
def int_hexagon_A2_min :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.min">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_min">;
//
// BUILTIN_INFO(HEXAGON.A2_minu,USI_ftype_SISI,2)
//
def int_hexagon_A2_minu :
-Hexagon_usi_sisi_Intrinsic<"HEXAGON.A2.minu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_minu">;
//
// BUILTIN_INFO(HEXAGON.A2_maxp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_maxp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.maxp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_maxp">;
//
// BUILTIN_INFO(HEXAGON.A2_maxup,UDI_ftype_DIDI,2)
//
def int_hexagon_A2_maxup :
-Hexagon_udi_didi_Intrinsic<"HEXAGON.A2.maxup">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_maxup">;
//
// BUILTIN_INFO(HEXAGON.A2_minp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_minp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.minp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_minp">;
//
// BUILTIN_INFO(HEXAGON.A2_minup,UDI_ftype_DIDI,2)
//
def int_hexagon_A2_minup :
-Hexagon_udi_didi_Intrinsic<"HEXAGON.A2.minup">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_minup">;
//
// BUILTIN_INFO(HEXAGON.A2_tfr,SI_ftype_SI,1)
//
def int_hexagon_A2_tfr :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.tfr">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_tfr">;
//
// BUILTIN_INFO(HEXAGON.A2_tfrsi,SI_ftype_SI,1)
//
def int_hexagon_A2_tfrsi :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.tfrsi">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_tfrsi">;
//
// BUILTIN_INFO(HEXAGON.A2_tfrp,DI_ftype_DI,1)
//
def int_hexagon_A2_tfrp :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.tfrp">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_tfrp">;
//
// BUILTIN_INFO(HEXAGON.A2_tfrpi,DI_ftype_SI,1)
//
def int_hexagon_A2_tfrpi :
-Hexagon_di_si_Intrinsic<"HEXAGON.A2.tfrpi">;
+Hexagon_di_si_Intrinsic<"HEXAGON_A2_tfrpi">;
//
// BUILTIN_INFO(HEXAGON.A2_zxtb,SI_ftype_SI,1)
//
def int_hexagon_A2_zxtb :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.zxtb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_zxtb">;
//
// BUILTIN_INFO(HEXAGON.A2_sxtb,SI_ftype_SI,1)
//
def int_hexagon_A2_sxtb :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.sxtb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sxtb">;
//
// BUILTIN_INFO(HEXAGON.A2_zxth,SI_ftype_SI,1)
//
def int_hexagon_A2_zxth :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.zxth">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_zxth">;
//
// BUILTIN_INFO(HEXAGON.A2_sxth,SI_ftype_SI,1)
//
def int_hexagon_A2_sxth :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.sxth">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sxth">;
//
// BUILTIN_INFO(HEXAGON.A2_combinew,DI_ftype_SISI,2)
//
def int_hexagon_A2_combinew :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.A2.combinew">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A2_combinew">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineri,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_combineri :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_combineri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_combineir :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_combineir">;
//
// BUILTIN_INFO(HEXAGON.A2_combineii,DI_ftype_SISI,2)
//
def int_hexagon_A2_combineii :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.A2.combineii">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A2_combineii">;
//
// BUILTIN_INFO(HEXAGON.A2_combine_hh,SI_ftype_SISI,2)
//
def int_hexagon_A2_combine_hh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.hh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_hh">;
//
// BUILTIN_INFO(HEXAGON.A2_combine_hl,SI_ftype_SISI,2)
//
def int_hexagon_A2_combine_hl :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.hl">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_hl">;
//
// BUILTIN_INFO(HEXAGON.A2_combine_lh,SI_ftype_SISI,2)
//
def int_hexagon_A2_combine_lh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.lh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_lh">;
//
// BUILTIN_INFO(HEXAGON.A2_combine_ll,SI_ftype_SISI,2)
//
def int_hexagon_A2_combine_ll :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.ll">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_ll">;
//
// BUILTIN_INFO(HEXAGON.A2_tfril,SI_ftype_SISI,2)
//
def int_hexagon_A2_tfril :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.tfril">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_tfril">;
//
// BUILTIN_INFO(HEXAGON.A2_tfrih,SI_ftype_SISI,2)
//
def int_hexagon_A2_tfrih :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.tfrih">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_tfrih">;
//
// BUILTIN_INFO(HEXAGON.A2_and,SI_ftype_SISI,2)
//
def int_hexagon_A2_and :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.and">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_and">;
//
// BUILTIN_INFO(HEXAGON.A2_or,SI_ftype_SISI,2)
//
def int_hexagon_A2_or :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.or">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_or">;
//
// BUILTIN_INFO(HEXAGON.A2_xor,SI_ftype_SISI,2)
//
def int_hexagon_A2_xor :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.xor">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_xor">;
//
// BUILTIN_INFO(HEXAGON.A2_not,SI_ftype_SI,1)
//
def int_hexagon_A2_not :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.not">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_not">;
//
// BUILTIN_INFO(HEXAGON.M2_xor_xacc,SI_ftype_SISISI,3)
//
def int_hexagon_M2_xor_xacc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.xor.xacc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_xor_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_xacc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_xor_xacc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_xor_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_andn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_andn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_orn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_orn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_orn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andnp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_andnp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A4_andnp">;
+//
+// BUILTIN_INFO(HEXAGON.A4_ornp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_ornp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A4_ornp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subaddi">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_xor">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andix,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andix :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_andix">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_andi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_ori,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_ori :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_ori">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_andn">;
//
// BUILTIN_INFO(HEXAGON.A2_subri,SI_ftype_SISI,2)
//
def int_hexagon_A2_subri :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subri">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subri">;
//
// BUILTIN_INFO(HEXAGON.A2_andir,SI_ftype_SISI,2)
//
def int_hexagon_A2_andir :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.andir">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_andir">;
//
// BUILTIN_INFO(HEXAGON.A2_orir,SI_ftype_SISI,2)
//
def int_hexagon_A2_orir :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.orir">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_orir">;
//
// BUILTIN_INFO(HEXAGON.A2_andp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_andp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.andp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_andp">;
//
// BUILTIN_INFO(HEXAGON.A2_orp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_orp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.orp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_orp">;
//
// BUILTIN_INFO(HEXAGON.A2_xorp,DI_ftype_DIDI,2)
//
def int_hexagon_A2_xorp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.xorp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_xorp">;
//
// BUILTIN_INFO(HEXAGON.A2_notp,DI_ftype_DI,1)
//
def int_hexagon_A2_notp :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.notp">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_notp">;
//
// BUILTIN_INFO(HEXAGON.A2_sxtw,DI_ftype_SI,1)
//
def int_hexagon_A2_sxtw :
-Hexagon_di_si_Intrinsic<"HEXAGON.A2.sxtw">;
+Hexagon_di_si_Intrinsic<"HEXAGON_A2_sxtw">;
//
// BUILTIN_INFO(HEXAGON.A2_sat,SI_ftype_DI,1)
//
def int_hexagon_A2_sat :
-Hexagon_si_di_Intrinsic<"HEXAGON.A2.sat">;
+Hexagon_si_di_Intrinsic<"HEXAGON_A2_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_roundsat,SI_ftype_DI,1)
+//
+def int_hexagon_A2_roundsat :
+Hexagon_si_di_Intrinsic<"HEXAGON_A2_roundsat">;
//
// BUILTIN_INFO(HEXAGON.A2_sath,SI_ftype_SI,1)
//
def int_hexagon_A2_sath :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.sath">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sath">;
//
// BUILTIN_INFO(HEXAGON.A2_satuh,SI_ftype_SI,1)
//
def int_hexagon_A2_satuh :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.satuh">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satuh">;
//
// BUILTIN_INFO(HEXAGON.A2_satub,SI_ftype_SI,1)
//
def int_hexagon_A2_satub :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.satub">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satub">;
//
// BUILTIN_INFO(HEXAGON.A2_satb,SI_ftype_SI,1)
//
def int_hexagon_A2_satb :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.satb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satb">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vaddub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddb_map,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddb_map :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddb_map">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddubs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vaddubs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddubs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddubs">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddh,DI_ftype_DIDI,2)
//
-def int_hexagon_A2_vaddh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddh">;
+def int_hexagon_A2_vaddh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddh">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddhs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vaddhs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddhs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddhs">;
//
// BUILTIN_INFO(HEXAGON.A2_vadduhs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vadduhs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vadduhs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vadduhs">;
+//
+// BUILTIN_INFO(HEXAGON.A5_vaddhubs,SI_ftype_DIDI,2)
+//
+def int_hexagon_A5_vaddhubs :
+Hexagon_si_didi_Intrinsic<"HEXAGON_A5_vaddhubs">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vaddw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddw">;
//
// BUILTIN_INFO(HEXAGON.A2_vaddws,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vaddws :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddws">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddws">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubw,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubw">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddw,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddw">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubh">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddh">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubhr">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddhr">;
//
// BUILTIN_INFO(HEXAGON.A2_svavgh,SI_ftype_SISI,2)
//
def int_hexagon_A2_svavgh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svavgh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svavgh">;
//
// BUILTIN_INFO(HEXAGON.A2_svavghs,SI_ftype_SISI,2)
//
def int_hexagon_A2_svavghs :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svavghs">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svavghs">;
//
// BUILTIN_INFO(HEXAGON.A2_svnavgh,SI_ftype_SISI,2)
//
def int_hexagon_A2_svnavgh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svnavgh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svnavgh">;
//
// BUILTIN_INFO(HEXAGON.A2_svaddh,SI_ftype_SISI,2)
//
def int_hexagon_A2_svaddh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svaddh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svaddh">;
//
// BUILTIN_INFO(HEXAGON.A2_svaddhs,SI_ftype_SISI,2)
//
def int_hexagon_A2_svaddhs :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svaddhs">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svaddhs">;
//
// BUILTIN_INFO(HEXAGON.A2_svadduhs,SI_ftype_SISI,2)
//
def int_hexagon_A2_svadduhs :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svadduhs">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svadduhs">;
//
// BUILTIN_INFO(HEXAGON.A2_svsubh,SI_ftype_SISI,2)
//
def int_hexagon_A2_svsubh :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubh">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubh">;
//
// BUILTIN_INFO(HEXAGON.A2_svsubhs,SI_ftype_SISI,2)
//
def int_hexagon_A2_svsubhs :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubhs">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubhs">;
//
// BUILTIN_INFO(HEXAGON.A2_svsubuhs,SI_ftype_SISI,2)
//
def int_hexagon_A2_svsubuhs :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubuhs">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubuhs">;
//
// BUILTIN_INFO(HEXAGON.A2_vraddub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vraddub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vraddub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vraddub">;
//
// BUILTIN_INFO(HEXAGON.A2_vraddub_acc,DI_ftype_DIDIDI,3)
//
def int_hexagon_A2_vraddub_acc :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.A2.vraddub.acc">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_A2_vraddub_acc">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vraddh,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vraddh :
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vraddh">;
//
// BUILTIN_INFO(HEXAGON.M2_vradduh,SI_ftype_DIDI,2)
//
def int_hexagon_M2_vradduh :
-Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vradduh">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vradduh">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubb_map,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubb_map :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubb_map">;
//
// BUILTIN_INFO(HEXAGON.A2_vsububs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsububs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsububs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsububs">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubh">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubhs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubhs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubhs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubhs">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubuhs,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubuhs :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubuhs">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubuhs">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubw">;
//
// BUILTIN_INFO(HEXAGON.A2_vsubws,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vsubws :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubws">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubws">;
//
// BUILTIN_INFO(HEXAGON.A2_vabsh,DI_ftype_DI,1)
//
def int_hexagon_A2_vabsh :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabsh">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabsh">;
//
// BUILTIN_INFO(HEXAGON.A2_vabshsat,DI_ftype_DI,1)
//
def int_hexagon_A2_vabshsat :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabshsat">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabshsat">;
//
// BUILTIN_INFO(HEXAGON.A2_vabsw,DI_ftype_DI,1)
//
def int_hexagon_A2_vabsw :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabsw">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabsw">;
//
// BUILTIN_INFO(HEXAGON.A2_vabswsat,DI_ftype_DI,1)
//
def int_hexagon_A2_vabswsat :
-Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabswsat">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabswsat">;
//
// BUILTIN_INFO(HEXAGON.M2_vabsdiffw,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vabsdiffw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vabsdiffw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vabsdiffw">;
//
// BUILTIN_INFO(HEXAGON.M2_vabsdiffh,DI_ftype_DIDI,2)
//
def int_hexagon_M2_vabsdiffh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vabsdiffh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vabsdiffh">;
//
// BUILTIN_INFO(HEXAGON.A2_vrsadub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vrsadub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vrsadub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vrsadub">;
//
// BUILTIN_INFO(HEXAGON.A2_vrsadub_acc,DI_ftype_DIDIDI,3)
//
def int_hexagon_A2_vrsadub_acc :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.A2.vrsadub.acc">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_A2_vrsadub_acc">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgub">;
//
// BUILTIN_INFO(HEXAGON.A2_vavguh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavguh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguh">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgh">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavgh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavgh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgh">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgw">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavgw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavgw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgw">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgwr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgwr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgwr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgwr">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavgwr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavgwr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgwr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgwr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgwcr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgwcr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgwcr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgwcr">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavgwcr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavgwcr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgwcr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgwcr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavghcr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavghcr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavghcr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavghcr">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavghcr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavghcr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavghcr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavghcr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavguw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavguw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguw">;
//
// BUILTIN_INFO(HEXAGON.A2_vavguwr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavguwr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguwr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguwr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavgubr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavgubr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgubr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgubr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavguhr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavguhr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguhr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguhr">;
//
// BUILTIN_INFO(HEXAGON.A2_vavghr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vavghr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavghr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavghr">;
//
// BUILTIN_INFO(HEXAGON.A2_vnavghr,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vnavghr :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavghr">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavghr">;
//
-// BUILTIN_INFO(HEXAGON.A2_vminh,DI_ftype_DIDI,2)
+// BUILTIN_INFO(HEXAGON.A4_round_ri,SI_ftype_SISI,2)
//
-def int_hexagon_A2_vminh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminh">;
+def int_hexagon_A4_round_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_ri">;
//
-// BUILTIN_INFO(HEXAGON.A2_vmaxh,DI_ftype_DIDI,2)
+// BUILTIN_INFO(HEXAGON.A4_round_rr,SI_ftype_SISI,2)
//
-def int_hexagon_A2_vmaxh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxh">;
+def int_hexagon_A4_round_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_ri_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_ri_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_ri_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_rr_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_rr_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_rr_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_ri,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cround_ri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_rr,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cround_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminuh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminuh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminuh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxuh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxuh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxuh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminuw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminuw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminuw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxuw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxuw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxuw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminb,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminb :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxb,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxb :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxb">;
//
// BUILTIN_INFO(HEXAGON.A2_vminub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vminub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminub">;
//
// BUILTIN_INFO(HEXAGON.A2_vmaxub,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vmaxub :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxub">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxh">;
//
// BUILTIN_INFO(HEXAGON.A2_vminuh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vminuh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminuh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminuh">;
//
// BUILTIN_INFO(HEXAGON.A2_vmaxuh,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vmaxuh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxuh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxuh">;
//
// BUILTIN_INFO(HEXAGON.A2_vminw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vminw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminw">;
//
// BUILTIN_INFO(HEXAGON.A2_vmaxw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vmaxw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxw">;
//
// BUILTIN_INFO(HEXAGON.A2_vminuw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vminuw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminuw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminuw">;
//
// BUILTIN_INFO(HEXAGON.A2_vmaxuw,DI_ftype_DIDI,2)
//
def int_hexagon_A2_vmaxuw :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxuw">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxuw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_modwrapu,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_modwrapu :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_modwrapu">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfadd,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfadd :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfadd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfsub,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfsub :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfsub">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmpy,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmpy :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmpy">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffma :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffma">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma_sc,SF_ftype_SFSFSFQI,4)
+//
+def int_hexagon_F2_sffma_sc :
+Hexagon_sf_sfsfsfqi_Intrinsic<"HEXAGON_F2_sffma_sc">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffms,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffms :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffms">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma_lib,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffma_lib :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffma_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffms_lib,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffms_lib :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffms_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpeq,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpeq :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpgt,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpgt :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpge,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpge :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpge">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpuo,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpuo :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpuo">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmax,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmax :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmax">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmin,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmin :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmin">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfclass,QI_ftype_SFSI,2)
+//
+def int_hexagon_F2_sfclass :
+Hexagon_qi_sfsi_Intrinsic<"HEXAGON_F2_sfclass">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfimm_p,SF_ftype_SI,1)
+//
+def int_hexagon_F2_sfimm_p :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_sfimm_p">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfimm_n,SF_ftype_SI,1)
+//
+def int_hexagon_F2_sfimm_n :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_sfimm_n">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupn,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sffixupn :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupn">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupd,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sffixupd :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupr,SF_ftype_SF,1)
+//
+def int_hexagon_F2_sffixupr :
+Hexagon_sf_sf_Intrinsic<"HEXAGON_F2_sffixupr">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfadd,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfadd :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfadd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfsub,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfsub :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfsub">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmpy,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmpy :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmpy">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffma :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffms,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffms :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma_lib,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffma_lib :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffms_lib,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffms_lib :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma_sc,DF_ftype_DFDFDFQI,4)
+//
+def int_hexagon_F2_dffma_sc :
+Hexagon_df_dfdfdfqi_Intrinsic<"HEXAGON_F2_dffma_sc">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmax,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmax :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmax">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmin,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmin :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmin">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpeq,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpeq :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpgt,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpgt :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpge,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpge :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpge">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpuo,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpuo :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpuo">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfclass,QI_ftype_DFSI,2)
+//
+def int_hexagon_F2_dfclass :
+Hexagon_qi_dfsi_Intrinsic<"HEXAGON_F2_dfclass">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfimm_p,DF_ftype_SI,1)
+//
+def int_hexagon_F2_dfimm_p :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_p">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfimm_n,DF_ftype_SI,1)
+//
+def int_hexagon_F2_dfimm_n :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_n">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupn,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dffixupn :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupn">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupd,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dffixupd :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupr,DF_ftype_DF,1)
+//
+def int_hexagon_F2_dffixupr :
+Hexagon_df_df_Intrinsic<"HEXAGON_F2_dffixupr">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2df,DF_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2df :
+Hexagon_df_sf_Intrinsic<"HEXAGON_F2_conv_sf2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2sf,SF_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2sf :
+Hexagon_sf_df_Intrinsic<"HEXAGON_F2_conv_df2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_uw2sf,SF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_uw2sf :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_conv_uw2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_uw2df,DF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_uw2df :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_conv_uw2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_w2sf,SF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_w2sf :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_conv_w2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_w2df,DF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_w2df :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_conv_w2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_ud2sf,SF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_ud2sf :
+Hexagon_sf_di_Intrinsic<"HEXAGON_F2_conv_ud2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_ud2df,DF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_ud2df :
+Hexagon_df_di_Intrinsic<"HEXAGON_F2_conv_ud2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_d2sf,SF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_d2sf :
+Hexagon_sf_di_Intrinsic<"HEXAGON_F2_conv_d2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_d2df,DF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_d2df :
+Hexagon_df_di_Intrinsic<"HEXAGON_F2_conv_d2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2uw,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2uw :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2uw">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2w,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2w :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2w">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2ud,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2ud :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2ud">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2d,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2d :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2d">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2uw,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2uw :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2uw">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2w,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2w :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2w">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2ud,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2ud :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2ud">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2d,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2d :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2d">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2uw_chop,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2uw_chop :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2uw_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2w_chop,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2w_chop :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2w_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2ud_chop,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2ud_chop :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2ud_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2d_chop,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2d_chop :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2d_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2uw_chop,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2uw_chop :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2uw_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2w_chop,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2w_chop :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2w_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2ud_chop,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2ud_chop :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2ud_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2d_chop,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2d_chop :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2d_chop">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_asr_r_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.r.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_r_r">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_asl_r_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.r.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_r_r">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_lsr_r_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsr.r.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsr_r_r">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_lsl_r_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsl.r.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsl_r_r">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_r_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_p">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_r_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_p">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_r_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_p">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsl_r_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_p">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_r_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_r_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_r_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsl_r_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_r_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_r_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_r_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsl_r_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_r_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_r_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_r_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsl_r_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_r_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_r_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_r_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsl_r_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_r_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_r_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_r_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsl_r_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_r_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_r_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_r_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsl_r_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_r_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_r_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_r_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsl_r_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_r_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_r_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_r_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsl_r_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_xor">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_r_sat,SI_ftype_SISI,2)
//
def int_hexagon_S2_asr_r_r_sat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.r.r.sat">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_r_r_sat">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_r_sat,SI_ftype_SISI,2)
//
def int_hexagon_S2_asl_r_r_sat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.r.r.sat">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_r_r_sat">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_asr_i_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_lsr_i_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsr.i.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsr_i_r">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_asl_i_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.i.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_i_r">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_i_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_i_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_p">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_i_p :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.p">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_p">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_i_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_i_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_acc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_i_r_acc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.acc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_i_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_i_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p_acc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_i_p_acc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.acc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_acc">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_i_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_i_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_nac,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_i_r_nac :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.nac">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_i_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_i_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p_nac,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_i_p_nac :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.nac">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_nac">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_xacc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_i_r_xacc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.xacc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_xacc,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_i_r_xacc :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.xacc">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_xacc">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_xacc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_i_p_xacc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.xacc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p_xacc,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_i_p_xacc :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.xacc">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_xacc">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_i_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_i_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_and,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_i_r_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asr_i_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_lsr_i_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_or,SI_ftype_SISISI,3)
//
def int_hexagon_S2_asl_i_r_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_i_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_i_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p_and,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_i_p_and :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.and">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_and">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asr_i_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_lsr_i_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_p_or,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_asl_i_p_or :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.or">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_or">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_r_sat,SI_ftype_SISI,2)
//
def int_hexagon_S2_asl_i_r_sat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.i.r.sat">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_i_r_sat">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd,SI_ftype_SISI,2)
//
def int_hexagon_S2_asr_i_r_rnd :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r.rnd">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r_rnd">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd_goodsyntax,SI_ftype_SISI,2)
//
def int_hexagon_S2_asr_i_r_rnd_goodsyntax :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r.rnd.goodsyntax">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_rnd,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p_rnd :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p_rnd">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_rnd_goodsyntax,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p_rnd_goodsyntax :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S4_lsli,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_lsli :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_lsli">;
//
// BUILTIN_INFO(HEXAGON.S2_addasl_rrri,SI_ftype_SISISI,3)
//
def int_hexagon_S2_addasl_rrri :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.addasl.rrri">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_addasl_rrri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_andi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_andi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_andi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ori_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_ori_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_ori_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_andi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_andi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_andi_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ori_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_ori_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_ori_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addi_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subi_lsr_ri">;
//
// BUILTIN_INFO(HEXAGON.S2_valignib,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_valignib :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.valignib">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_valignib">;
//
// BUILTIN_INFO(HEXAGON.S2_valignrb,DI_ftype_DIDIQI,3)
//
def int_hexagon_S2_valignrb :
-Hexagon_di_didiqi_Intrinsic<"HEXAGON.S2.valignrb">;
+Hexagon_di_didiqi_Intrinsic<"HEXAGON_S2_valignrb">;
//
// BUILTIN_INFO(HEXAGON.S2_vspliceib,DI_ftype_DIDISI,3)
//
def int_hexagon_S2_vspliceib :
-Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.vspliceib">;
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_vspliceib">;
//
// BUILTIN_INFO(HEXAGON.S2_vsplicerb,DI_ftype_DIDIQI,3)
//
def int_hexagon_S2_vsplicerb :
-Hexagon_di_didiqi_Intrinsic<"HEXAGON.S2.vsplicerb">;
+Hexagon_di_didiqi_Intrinsic<"HEXAGON_S2_vsplicerb">;
//
// BUILTIN_INFO(HEXAGON.S2_vsplatrh,DI_ftype_SI,1)
//
def int_hexagon_S2_vsplatrh :
-Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsplatrh">;
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsplatrh">;
//
// BUILTIN_INFO(HEXAGON.S2_vsplatrb,SI_ftype_SI,1)
//
def int_hexagon_S2_vsplatrb :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.vsplatrb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_vsplatrb">;
//
// BUILTIN_INFO(HEXAGON.S2_insert,SI_ftype_SISISISI,4)
//
def int_hexagon_S2_insert :
-Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.insert">;
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_insert">;
//
// BUILTIN_INFO(HEXAGON.S2_tableidxb_goodsyntax,SI_ftype_SISISISI,4)
//
def int_hexagon_S2_tableidxb_goodsyntax :
-Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxb.goodsyntax">;
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxb_goodsyntax">;
//
// BUILTIN_INFO(HEXAGON.S2_tableidxh_goodsyntax,SI_ftype_SISISISI,4)
//
def int_hexagon_S2_tableidxh_goodsyntax :
-Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxh.goodsyntax">;
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxh_goodsyntax">;
//
// BUILTIN_INFO(HEXAGON.S2_tableidxw_goodsyntax,SI_ftype_SISISISI,4)
//
def int_hexagon_S2_tableidxw_goodsyntax :
-Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxw.goodsyntax">;
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxw_goodsyntax">;
//
// BUILTIN_INFO(HEXAGON.S2_tableidxd_goodsyntax,SI_ftype_SISISISI,4)
//
def int_hexagon_S2_tableidxd_goodsyntax :
-Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxd.goodsyntax">;
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.A4_bitspliti,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_bitspliti :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_bitspliti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_bitsplit,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_bitsplit :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_bitsplit">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extract,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_extract :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_extract">;
//
// BUILTIN_INFO(HEXAGON.S2_extractu,SI_ftype_SISISI,3)
//
def int_hexagon_S2_extractu :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.extractu">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_extractu">;
//
// BUILTIN_INFO(HEXAGON.S2_insertp,DI_ftype_DIDISISI,4)
//
def int_hexagon_S2_insertp :
-Hexagon_di_didisisi_Intrinsic<"HEXAGON.S2.insertp">;
+Hexagon_di_didisisi_Intrinsic<"HEXAGON_S2_insertp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extractp,DI_ftype_DISISI,3)
+//
+def int_hexagon_S4_extractp :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S4_extractp">;
//
// BUILTIN_INFO(HEXAGON.S2_extractup,DI_ftype_DISISI,3)
//
def int_hexagon_S2_extractup :
-Hexagon_di_disisi_Intrinsic<"HEXAGON.S2.extractup">;
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S2_extractup">;
//
// BUILTIN_INFO(HEXAGON.S2_insert_rp,SI_ftype_SISIDI,3)
//
def int_hexagon_S2_insert_rp :
-Hexagon_si_sisidi_Intrinsic<"HEXAGON.S2.insert.rp">;
+Hexagon_si_sisidi_Intrinsic<"HEXAGON_S2_insert_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extract_rp,SI_ftype_SIDI,2)
+//
+def int_hexagon_S4_extract_rp :
+Hexagon_si_sidi_Intrinsic<"HEXAGON_S4_extract_rp">;
//
// BUILTIN_INFO(HEXAGON.S2_extractu_rp,SI_ftype_SIDI,2)
//
def int_hexagon_S2_extractu_rp :
-Hexagon_si_sidi_Intrinsic<"HEXAGON.S2.extractu.rp">;
+Hexagon_si_sidi_Intrinsic<"HEXAGON_S2_extractu_rp">;
//
// BUILTIN_INFO(HEXAGON.S2_insertp_rp,DI_ftype_DIDIDI,3)
//
def int_hexagon_S2_insertp_rp :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.S2.insertp.rp">;
+Hexagon_di_dididi_Intrinsic<"HEXAGON_S2_insertp_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extractp_rp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_extractp_rp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_extractp_rp">;
//
// BUILTIN_INFO(HEXAGON.S2_extractup_rp,DI_ftype_DIDI,2)
//
def int_hexagon_S2_extractup_rp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.extractup.rp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_extractup_rp">;
//
// BUILTIN_INFO(HEXAGON.S2_tstbit_i,QI_ftype_SISI,2)
//
def int_hexagon_S2_tstbit_i :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.S2.tstbit.i">;
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ntstbit_i,QI_ftype_SISI,2)
+//
+def int_hexagon_S4_ntstbit_i :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_i">;
//
// BUILTIN_INFO(HEXAGON.S2_setbit_i,SI_ftype_SISI,2)
//
def int_hexagon_S2_setbit_i :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.setbit.i">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_setbit_i">;
//
// BUILTIN_INFO(HEXAGON.S2_togglebit_i,SI_ftype_SISI,2)
//
def int_hexagon_S2_togglebit_i :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.togglebit.i">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_togglebit_i">;
//
// BUILTIN_INFO(HEXAGON.S2_clrbit_i,SI_ftype_SISI,2)
//
def int_hexagon_S2_clrbit_i :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.clrbit.i">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_clrbit_i">;
//
// BUILTIN_INFO(HEXAGON.S2_tstbit_r,QI_ftype_SISI,2)
//
def int_hexagon_S2_tstbit_r :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.S2.tstbit.r">;
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ntstbit_r,QI_ftype_SISI,2)
+//
+def int_hexagon_S4_ntstbit_r :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_r">;
//
// BUILTIN_INFO(HEXAGON.S2_setbit_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_setbit_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.setbit.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_setbit_r">;
//
// BUILTIN_INFO(HEXAGON.S2_togglebit_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_togglebit_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.togglebit.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_togglebit_r">;
//
// BUILTIN_INFO(HEXAGON.S2_clrbit_r,SI_ftype_SISI,2)
//
def int_hexagon_S2_clrbit_r :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.clrbit.r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_clrbit_r">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_i_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_i_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_i_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_r_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S5_asrhub_rnd_sat_goodsyntax,SI_ftype_DISI,2)
+//
+def int_hexagon_S5_asrhub_rnd_sat_goodsyntax :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S5_asrhub_sat,SI_ftype_DISI,2)
+//
+def int_hexagon_S5_asrhub_sat :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S5_asrhub_sat">;
+//
+// BUILTIN_INFO(HEXAGON.S5_vasrhrnd_goodsyntax,DI_ftype_DISI,2)
+//
+def int_hexagon_S5_vasrhrnd_goodsyntax :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_r_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_r_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_vh,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsl_r_vh :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.vh">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_vh">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_i_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_i_svw_trun,SI_ftype_DISI,2)
//
def int_hexagon_S2_asr_i_svw_trun :
-Hexagon_si_disi_Intrinsic<"HEXAGON.S2.asr.i.svw.trun">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_S2_asr_i_svw_trun">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_svw_trun,SI_ftype_DISI,2)
//
def int_hexagon_S2_asr_r_svw_trun :
-Hexagon_si_disi_Intrinsic<"HEXAGON.S2.asr.r.svw.trun">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_S2_asr_r_svw_trun">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_i_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_i_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_i_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_i_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_asr_r_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_asr_r_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_asl_r_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_asl_r_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_lsr_r_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsr_r_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_lsl_r_vw,DI_ftype_DISI,2)
//
def int_hexagon_S2_lsl_r_vw :
-Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.vw">;
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_vw">;
//
// BUILTIN_INFO(HEXAGON.S2_vrndpackwh,SI_ftype_DI,1)
//
def int_hexagon_S2_vrndpackwh :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vrndpackwh">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vrndpackwh">;
//
// BUILTIN_INFO(HEXAGON.S2_vrndpackwhs,SI_ftype_DI,1)
//
def int_hexagon_S2_vrndpackwhs :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vrndpackwhs">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vrndpackwhs">;
//
// BUILTIN_INFO(HEXAGON.S2_vsxtbh,DI_ftype_SI,1)
//
def int_hexagon_S2_vsxtbh :
-Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsxtbh">;
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsxtbh">;
//
// BUILTIN_INFO(HEXAGON.S2_vzxtbh,DI_ftype_SI,1)
//
def int_hexagon_S2_vzxtbh :
-Hexagon_di_si_Intrinsic<"HEXAGON.S2.vzxtbh">;
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vzxtbh">;
//
// BUILTIN_INFO(HEXAGON.S2_vsathub,SI_ftype_DI,1)
//
def int_hexagon_S2_vsathub :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsathub">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsathub">;
//
// BUILTIN_INFO(HEXAGON.S2_svsathub,SI_ftype_SI,1)
//
def int_hexagon_S2_svsathub :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.svsathub">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_svsathub">;
//
// BUILTIN_INFO(HEXAGON.S2_svsathb,SI_ftype_SI,1)
//
def int_hexagon_S2_svsathb :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.svsathb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_svsathb">;
//
// BUILTIN_INFO(HEXAGON.S2_vsathb,SI_ftype_DI,1)
//
def int_hexagon_S2_vsathb :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsathb">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsathb">;
//
// BUILTIN_INFO(HEXAGON.S2_vtrunohb,SI_ftype_DI,1)
//
def int_hexagon_S2_vtrunohb :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vtrunohb">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vtrunohb">;
//
// BUILTIN_INFO(HEXAGON.S2_vtrunewh,DI_ftype_DIDI,2)
//
def int_hexagon_S2_vtrunewh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.vtrunewh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_vtrunewh">;
//
// BUILTIN_INFO(HEXAGON.S2_vtrunowh,DI_ftype_DIDI,2)
//
def int_hexagon_S2_vtrunowh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.vtrunowh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_vtrunowh">;
//
// BUILTIN_INFO(HEXAGON.S2_vtrunehb,SI_ftype_DI,1)
//
def int_hexagon_S2_vtrunehb :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vtrunehb">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vtrunehb">;
//
// BUILTIN_INFO(HEXAGON.S2_vsxthw,DI_ftype_SI,1)
//
def int_hexagon_S2_vsxthw :
-Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsxthw">;
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsxthw">;
//
// BUILTIN_INFO(HEXAGON.S2_vzxthw,DI_ftype_SI,1)
//
def int_hexagon_S2_vzxthw :
-Hexagon_di_si_Intrinsic<"HEXAGON.S2.vzxthw">;
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vzxthw">;
//
// BUILTIN_INFO(HEXAGON.S2_vsatwh,SI_ftype_DI,1)
//
def int_hexagon_S2_vsatwh :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsatwh">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsatwh">;
//
// BUILTIN_INFO(HEXAGON.S2_vsatwuh,SI_ftype_DI,1)
//
def int_hexagon_S2_vsatwuh :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsatwuh">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsatwuh">;
//
// BUILTIN_INFO(HEXAGON.S2_packhl,DI_ftype_SISI,2)
//
def int_hexagon_S2_packhl :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.S2.packhl">;
+Hexagon_di_sisi_Intrinsic<"HEXAGON_S2_packhl">;
//
// BUILTIN_INFO(HEXAGON.A2_swiz,SI_ftype_SI,1)
//
def int_hexagon_A2_swiz :
-Hexagon_si_si_Intrinsic<"HEXAGON.A2.swiz">;
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_swiz">;
//
// BUILTIN_INFO(HEXAGON.S2_vsathub_nopack,DI_ftype_DI,1)
//
def int_hexagon_S2_vsathub_nopack :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsathub.nopack">;
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsathub_nopack">;
//
// BUILTIN_INFO(HEXAGON.S2_vsathb_nopack,DI_ftype_DI,1)
//
def int_hexagon_S2_vsathb_nopack :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsathb.nopack">;
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsathb_nopack">;
//
// BUILTIN_INFO(HEXAGON.S2_vsatwh_nopack,DI_ftype_DI,1)
//
def int_hexagon_S2_vsatwh_nopack :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsatwh.nopack">;
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsatwh_nopack">;
//
// BUILTIN_INFO(HEXAGON.S2_vsatwuh_nopack,DI_ftype_DI,1)
//
def int_hexagon_S2_vsatwuh_nopack :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsatwuh.nopack">;
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsatwuh_nopack">;
//
// BUILTIN_INFO(HEXAGON.S2_shuffob,DI_ftype_DIDI,2)
//
def int_hexagon_S2_shuffob :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffob">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffob">;
//
// BUILTIN_INFO(HEXAGON.S2_shuffeb,DI_ftype_DIDI,2)
//
def int_hexagon_S2_shuffeb :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffeb">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffeb">;
//
// BUILTIN_INFO(HEXAGON.S2_shuffoh,DI_ftype_DIDI,2)
//
def int_hexagon_S2_shuffoh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffoh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffoh">;
//
// BUILTIN_INFO(HEXAGON.S2_shuffeh,DI_ftype_DIDI,2)
//
def int_hexagon_S2_shuffeh :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffeh">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffeh">;
+//
+// BUILTIN_INFO(HEXAGON.S5_popcountp,SI_ftype_DI,1)
+//
+def int_hexagon_S5_popcountp :
+Hexagon_si_di_Intrinsic<"HEXAGON_S5_popcountp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_parity,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_parity :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_parity">;
//
// BUILTIN_INFO(HEXAGON.S2_parityp,SI_ftype_DIDI,2)
//
def int_hexagon_S2_parityp :
-Hexagon_si_didi_Intrinsic<"HEXAGON.S2.parityp">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_S2_parityp">;
//
// BUILTIN_INFO(HEXAGON.S2_lfsp,DI_ftype_DIDI,2)
//
def int_hexagon_S2_lfsp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S2.lfsp">;
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_lfsp">;
//
// BUILTIN_INFO(HEXAGON.S2_clbnorm,SI_ftype_SI,1)
//
def int_hexagon_S2_clbnorm :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.clbnorm">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_clbnorm">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbaddi,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_clbaddi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_clbaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbpnorm,SI_ftype_DI,1)
+//
+def int_hexagon_S4_clbpnorm :
+Hexagon_si_di_Intrinsic<"HEXAGON_S4_clbpnorm">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbpaddi,SI_ftype_DISI,2)
+//
+def int_hexagon_S4_clbpaddi :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S4_clbpaddi">;
//
// BUILTIN_INFO(HEXAGON.S2_clb,SI_ftype_SI,1)
//
def int_hexagon_S2_clb :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.clb">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_clb">;
//
// BUILTIN_INFO(HEXAGON.S2_cl0,SI_ftype_SI,1)
//
def int_hexagon_S2_cl0 :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.cl0">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_cl0">;
//
// BUILTIN_INFO(HEXAGON.S2_cl1,SI_ftype_SI,1)
//
def int_hexagon_S2_cl1 :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.cl1">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_cl1">;
//
// BUILTIN_INFO(HEXAGON.S2_clbp,SI_ftype_DI,1)
//
def int_hexagon_S2_clbp :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.clbp">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_clbp">;
//
// BUILTIN_INFO(HEXAGON.S2_cl0p,SI_ftype_DI,1)
//
def int_hexagon_S2_cl0p :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.cl0p">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_cl0p">;
//
// BUILTIN_INFO(HEXAGON.S2_cl1p,SI_ftype_DI,1)
//
def int_hexagon_S2_cl1p :
-Hexagon_si_di_Intrinsic<"HEXAGON.S2.cl1p">;
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_cl1p">;
//
// BUILTIN_INFO(HEXAGON.S2_brev,SI_ftype_SI,1)
//
def int_hexagon_S2_brev :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.brev">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_brev">;
+//
+// BUILTIN_INFO(HEXAGON.S2_brevp,DI_ftype_DI,1)
+//
+def int_hexagon_S2_brevp :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_brevp">;
//
// BUILTIN_INFO(HEXAGON.S2_ct0,SI_ftype_SI,1)
//
def int_hexagon_S2_ct0 :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.ct0">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_ct0">;
//
// BUILTIN_INFO(HEXAGON.S2_ct1,SI_ftype_SI,1)
//
def int_hexagon_S2_ct1 :
-Hexagon_si_si_Intrinsic<"HEXAGON.S2.ct1">;
-//
-// BUILTIN_INFO(HEXAGON.S2_interleave,DI_ftype_DI,1)
-//
-def int_hexagon_S2_interleave :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.interleave">;
-//
-// BUILTIN_INFO(HEXAGON.S2_deinterleave,DI_ftype_DI,1)
-//
-def int_hexagon_S2_deinterleave :
-Hexagon_di_di_Intrinsic<"HEXAGON.S2.deinterleave">;
-
-//
-// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
-//
-def int_hexagon_SI_to_SXTHI_asrh :
-Hexagon_si_si_Intrinsic<"SI.to.SXTHI.asrh">;
-
-//
-// BUILTIN_INFO(HEXAGON.A4_orn,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_orn :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.orn">;
-//
-// BUILTIN_INFO(HEXAGON.A4_andn,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_andn :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.andn">;
-//
-// BUILTIN_INFO(HEXAGON.A4_orn,DI_ftype_DIDI,2)
-//
-def int_hexagon_A4_ornp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A4.ornp">;
-//
-// BUILTIN_INFO(HEXAGON.A4_andn,DI_ftype_DIDI,2)
-//
-def int_hexagon_A4_andnp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.A4.andnp">;
-//
-// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_sisi,2)
-//
-def int_hexagon_A4_combineir :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.A4.combineir">;
-//
-// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_sisi,2)
-//
-def int_hexagon_A4_combineri :
-Hexagon_di_sisi_Intrinsic<"HEXAGON.A4.combineri">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmpneq,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmpneq :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpneq">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmpneqi,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmpneqi :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpneqi">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmplte,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmplte :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplte">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmpltei,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmpltei :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpltei">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmplteu,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmplteu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplteu">;
-//
-// BUILTIN_INFO(HEXAGON.C4_cmplteui,QI_ftype_SISI,2)
-//
-def int_hexagon_C4_cmplteui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplteui">;
-//
-// BUILTIN_INFO(HEXAGON.A4_rcmpneq,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_rcmpneq :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpneq">;
-//
-// BUILTIN_INFO(HEXAGON.A4_rcmpneqi,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_rcmpneqi :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpneqi">;
-//
-// BUILTIN_INFO(HEXAGON.A4_rcmpeq,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_rcmpeq :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpeq">;
-//
-// BUILTIN_INFO(HEXAGON.A4_rcmpeqi,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_rcmpeqi :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpeqi">;
-//
-// BUILTIN_INFO(HEXAGON.C4_fastcorner9,QI_ftype_QIQI,2)
-//
-def int_hexagon_C4_fastcorner9 :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C4.fastcorner9">;
-//
-// BUILTIN_INFO(HEXAGON.C4_fastcorner9_not,QI_ftype_QIQI,2)
-//
-def int_hexagon_C4_fastcorner9_not :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C4.fastcorner9_not">;
-//
-// BUILTIN_INFO(HEXAGON.C4_and_andn,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_and_andn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_andn">;
-//
-// BUILTIN_INFO(HEXAGON.C4_and_and,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_and_and :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_and">;
-//
-// BUILTIN_INFO(HEXAGON.C4_and_orn,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_and_orn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_orn">;
-//
-// BUILTIN_INFO(HEXAGON.C4_and_or,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_and_or :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_or">;
-//
-// BUILTIN_INFO(HEXAGON.C4_or_andn,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_or_andn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_andn">;
-//
-// BUILTIN_INFO(HEXAGON.C4_or_and,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_or_and :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_and">;
-//
-// BUILTIN_INFO(HEXAGON.C4_or_orn,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_or_orn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_orn">;
-//
-// BUILTIN_INFO(HEXAGON.C4_or_or,QI_ftype_QIQIQI,3)
-//
-def int_hexagon_C4_or_or :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_or">;
-//
-// BUILTIN_INFO(HEXAGON.S4_addaddi,SI_ftype_SISISI,3)
-//
-def int_hexagon_S4_addaddi :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.addaddi">;
-//
-// BUILTIN_INFO(HEXAGON.S4_subaddi,SI_ftype_SISISI,3)
-//
-def int_hexagon_S4_subaddi :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.subaddi">;
-//
-// BUILTIN_INFO(HEXAGON.S4_andnp,DI_ftype_DIDI,2)
-//
-def int_hexagon_S4_andnp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S4.andnp">;
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_ct1">;
//
-// BUILTIN_INFO(HEXAGON.S4_ornp,DI_ftype_DIDI,2)
+// BUILTIN_INFO(HEXAGON.S2_ct0p,SI_ftype_DI,1)
//
-def int_hexagon_S4_ornp :
-Hexagon_di_didi_Intrinsic<"HEXAGON.S4.ornp">;
+def int_hexagon_S2_ct0p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_ct0p">;
//
-// BUILTIN_INFO(HEXAGON.M4_xor_xacc,DI_ftype_DIDIDI,3)
-//
-def int_hexagon_M4_xor_xacc :
-Hexagon_di_dididi_Intrinsic<"HEXAGON.M4.xor_xacc">;
-//
-// BUILTIN_INFO(HEXAGON.M4_and_and,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_and_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_and">;
+// BUILTIN_INFO(HEXAGON.S2_ct1p,SI_ftype_DI,1)
//
-// BUILTIN_INFO(HEXAGON.M4_and_andn,SI_ftype_SISISI,3)
+def int_hexagon_S2_ct1p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_ct1p">;
//
-def int_hexagon_M4_and_andn :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_andn">;
-//
-// BUILTIN_INFO(HEXAGON.M4_and_or,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_and_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_or">;
-//
-// BUILTIN_INFO(HEXAGON.M4_and_xor,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_and_xor :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_xor">;
-//
-// BUILTIN_INFO(HEXAGON.M4_xor_and,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_xor_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_or">;
-//
-// BUILTIN_INFO(HEXAGON.M4_xor_or,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_xor_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_and">;
-//
-// BUILTIN_INFO(HEXAGON.M4_xor_andn,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_xor_andn :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_andn">;
-//
-// BUILTIN_INFO(HEXAGON.M4_or_and,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_or_and :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_and">;
-//
-// BUILTIN_INFO(HEXAGON.M4_or_or,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_or_or :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_or">;
-//
-// BUILTIN_INFO(HEXAGON.M4_or_xor,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_or_xor :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_xor">;
-//
-// BUILTIN_INFO(HEXAGON.M4_or_andn,SI_ftype_SISISI,3)
-//
-def int_hexagon_M4_or_andn :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_andn">;
-//
-// BUILTIN_INFO(HEXAGON.S4_or_andix,SI_ftype_SISISI,3)
-//
-def int_hexagon_S4_or_andix :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_andix">;
-//
-// BUILTIN_INFO(HEXAGON.S4_or_andi,SI_ftype_SISISI,3)
-//
-def int_hexagon_S4_or_andi :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_andi">;
-//
-// BUILTIN_INFO(HEXAGON.S4_or_ori,SI_ftype_SISISI,3)
-//
-def int_hexagon_S4_or_ori :
-Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_ori">;
-//
-// BUILTIN_INFO(HEXAGON.A4_modwrapu,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_modwrapu :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.modwrapu">;
-//
-// BUILTIN_INFO(HEXAGON.A4_cround_ri,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_cround_ri :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.cround_ri">;
-//
-// BUILTIN_INFO(HEXAGON.A4_cround_rr,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_cround_rr :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.cround_rr">;
-//
-// BUILTIN_INFO(HEXAGON.A4_round_ri,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_round_ri :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_ri">;
-//
-// BUILTIN_INFO(HEXAGON.A4_round_rr,SI_ftype_SISI,2)
-//
-def int_hexagon_A4_round_rr :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_rr">;
-//
-// BUILTIN_INFO(HEXAGON.A4_round_ri_sat,SI_ftype_SISI,2)
+// BUILTIN_INFO(HEXAGON.S2_interleave,DI_ftype_DI,1)
//
-def int_hexagon_A4_round_ri_sat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_ri_sat">;
+def int_hexagon_S2_interleave :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_interleave">;
//
-// BUILTIN_INFO(HEXAGON.A4_round_rr_sat,SI_ftype_SISI,2)
+// BUILTIN_INFO(HEXAGON.S2_deinterleave,DI_ftype_DI,1)
//
-def int_hexagon_A4_round_rr_sat :
-Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_rr_sat">;
+def int_hexagon_S2_deinterleave :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_deinterleave">;
diff --git a/include/llvm/IntrinsicsMips.td b/include/llvm/IntrinsicsMips.td
new file mode 100644
index 000000000000..4375ac2a7a1b
--- /dev/null
+++ b/include/llvm/IntrinsicsMips.td
@@ -0,0 +1,264 @@
+//===- IntrinsicsMips.td - Defines Mips intrinsics ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the MIPS-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MIPS DSP data types
+def mips_v2q15_ty: LLVMType<v2i16>;
+def mips_q31_ty: LLVMType<i32>;
+
+let TargetPrefix = "mips" in { // All intrinsics start with "llvm.mips.".
+
+//===----------------------------------------------------------------------===//
+// Addition/subtraction
+
+def int_mips_addu_qb : GCCBuiltin<"__builtin_mips_addu_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_addu_s_qb : GCCBuiltin<"__builtin_mips_addu_s_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_subu_qb : GCCBuiltin<"__builtin_mips_subu_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_subu_s_qb : GCCBuiltin<"__builtin_mips_subu_s_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+
+def int_mips_addq_ph : GCCBuiltin<"__builtin_mips_addq_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_addq_s_ph : GCCBuiltin<"__builtin_mips_addq_s_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_subq_ph : GCCBuiltin<"__builtin_mips_subq_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_subq_s_ph : GCCBuiltin<"__builtin_mips_subq_s_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+
+def int_mips_madd: GCCBuiltin<"__builtin_mips_madd">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+def int_mips_maddu: GCCBuiltin<"__builtin_mips_maddu">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+def int_mips_msub: GCCBuiltin<"__builtin_mips_msub">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_mips_msubu: GCCBuiltin<"__builtin_mips_msubu">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+def int_mips_addq_s_w: GCCBuiltin<"__builtin_mips_addq_s_w">,
+ Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>;
+def int_mips_subq_s_w: GCCBuiltin<"__builtin_mips_subq_s_w">,
+ Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], []>;
+
+def int_mips_addsc: GCCBuiltin<"__builtin_mips_addsc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;
+def int_mips_addwc: GCCBuiltin<"__builtin_mips_addwc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;
+
+def int_mips_modsub: GCCBuiltin<"__builtin_mips_modsub">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_raddu_w_qb: GCCBuiltin<"__builtin_mips_raddu_w_qb">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Absolute value
+
+def int_mips_absq_s_ph: GCCBuiltin<"__builtin_mips_absq_s_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty], []>;
+def int_mips_absq_s_w: GCCBuiltin<"__builtin_mips_absq_s_w">,
+ Intrinsic<[mips_q31_ty], [mips_q31_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Precision reduce/expand
+
+def int_mips_precrq_qb_ph: GCCBuiltin<"__builtin_mips_precrq_qb_ph">,
+ Intrinsic<[llvm_v4i8_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_precrqu_s_qb_ph: GCCBuiltin<"__builtin_mips_precrqu_s_qb_ph">,
+ Intrinsic<[llvm_v4i8_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_precrq_ph_w: GCCBuiltin<"__builtin_mips_precrq_ph_w">,
+ Intrinsic<[mips_v2q15_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>;
+def int_mips_precrq_rs_ph_w: GCCBuiltin<"__builtin_mips_precrq_rs_ph_w">,
+ Intrinsic<[mips_v2q15_ty], [mips_q31_ty, mips_q31_ty], []>;
+def int_mips_preceq_w_phl: GCCBuiltin<"__builtin_mips_preceq_w_phl">,
+ Intrinsic<[mips_q31_ty], [mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_preceq_w_phr: GCCBuiltin<"__builtin_mips_preceq_w_phr">,
+ Intrinsic<[mips_q31_ty], [mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbl: GCCBuiltin<"__builtin_mips_precequ_ph_qbl">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbr: GCCBuiltin<"__builtin_mips_precequ_ph_qbr">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbla: GCCBuiltin<"__builtin_mips_precequ_ph_qbla">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbra: GCCBuiltin<"__builtin_mips_precequ_ph_qbra">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbl: GCCBuiltin<"__builtin_mips_preceu_ph_qbl">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbr: GCCBuiltin<"__builtin_mips_preceu_ph_qbr">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbla: GCCBuiltin<"__builtin_mips_preceu_ph_qbla">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbra: GCCBuiltin<"__builtin_mips_preceu_ph_qbra">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Shift
+
+def int_mips_shll_qb: GCCBuiltin<"__builtin_mips_shll_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], []>;
+def int_mips_shrl_qb: GCCBuiltin<"__builtin_mips_shrl_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shll_ph: GCCBuiltin<"__builtin_mips_shll_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], []>;
+def int_mips_shll_s_ph: GCCBuiltin<"__builtin_mips_shll_s_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], []>;
+def int_mips_shra_ph: GCCBuiltin<"__builtin_mips_shra_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shra_r_ph: GCCBuiltin<"__builtin_mips_shra_r_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shll_s_w: GCCBuiltin<"__builtin_mips_shll_s_w">,
+ Intrinsic<[mips_q31_ty], [mips_q31_ty, llvm_i32_ty], []>;
+def int_mips_shra_r_w: GCCBuiltin<"__builtin_mips_shra_r_w">,
+ Intrinsic<[mips_q31_ty], [mips_q31_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shilo: GCCBuiltin<"__builtin_mips_shilo">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Multiplication
+
+def int_mips_muleu_s_ph_qbl: GCCBuiltin<"__builtin_mips_muleu_s_ph_qbl">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty, mips_v2q15_ty], []>;
+def int_mips_muleu_s_ph_qbr: GCCBuiltin<"__builtin_mips_muleu_s_ph_qbr">,
+ Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty, mips_v2q15_ty], []>;
+def int_mips_mulq_rs_ph: GCCBuiltin<"__builtin_mips_mulq_rs_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_muleq_s_w_phl: GCCBuiltin<"__builtin_mips_muleq_s_w_phl">,
+ Intrinsic<[mips_q31_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_muleq_s_w_phr: GCCBuiltin<"__builtin_mips_muleq_s_w_phr">,
+ Intrinsic<[mips_q31_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_mulsaq_s_w_ph: GCCBuiltin<"__builtin_mips_mulsaq_s_w_ph">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_s_w_phl: GCCBuiltin<"__builtin_mips_maq_s_w_phl">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_s_w_phr: GCCBuiltin<"__builtin_mips_maq_s_w_phr">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_sa_w_phl: GCCBuiltin<"__builtin_mips_maq_sa_w_phl">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_sa_w_phr: GCCBuiltin<"__builtin_mips_maq_sa_w_phr">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_mult: GCCBuiltin<"__builtin_mips_mult">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+def int_mips_multu: GCCBuiltin<"__builtin_mips_multu">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+//===----------------------------------------------------------------------===//
+// Dot product with accumulate/subtract
+
+def int_mips_dpau_h_qbl: GCCBuiltin<"__builtin_mips_dpau_h_qbl">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+ [IntrNoMem]>;
+def int_mips_dpau_h_qbr: GCCBuiltin<"__builtin_mips_dpau_h_qbr">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+ [IntrNoMem]>;
+def int_mips_dpsu_h_qbl: GCCBuiltin<"__builtin_mips_dpsu_h_qbl">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+ [IntrNoMem]>;
+def int_mips_dpsu_h_qbr: GCCBuiltin<"__builtin_mips_dpsu_h_qbr">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+ [IntrNoMem]>;
+def int_mips_dpaq_s_w_ph: GCCBuiltin<"__builtin_mips_dpaq_s_w_ph">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpsq_s_w_ph: GCCBuiltin<"__builtin_mips_dpsq_s_w_ph">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpaq_sa_l_w: GCCBuiltin<"__builtin_mips_dpaq_sa_l_w">,
+ 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">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Comparison
+
+def int_mips_cmpu_eq_qb: GCCBuiltin<"__builtin_mips_cmpu_eq_qb">,
+ Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpu_lt_qb: GCCBuiltin<"__builtin_mips_cmpu_lt_qb">,
+ Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpu_le_qb: GCCBuiltin<"__builtin_mips_cmpu_le_qb">,
+ Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpgu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgu_eq_qb">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpgu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgu_lt_qb">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpgu_le_qb: GCCBuiltin<"__builtin_mips_cmpgu_le_qb">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmp_eq_ph: GCCBuiltin<"__builtin_mips_cmp_eq_ph">,
+ Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_cmp_lt_ph: GCCBuiltin<"__builtin_mips_cmp_lt_ph">,
+ Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_cmp_le_ph: GCCBuiltin<"__builtin_mips_cmp_le_ph">,
+ Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+
+//===----------------------------------------------------------------------===//
+// Extracting
+
+def int_mips_extr_s_h: GCCBuiltin<"__builtin_mips_extr_s_h">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_w: GCCBuiltin<"__builtin_mips_extr_w">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_rs_w: GCCBuiltin<"__builtin_mips_extr_rs_w">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_r_w: GCCBuiltin<"__builtin_mips_extr_r_w">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extp: GCCBuiltin<"__builtin_mips_extp">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extpdp: GCCBuiltin<"__builtin_mips_extpdp">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Misc
+
+def int_mips_wrdsp: GCCBuiltin<"__builtin_mips_wrdsp">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_mips_rddsp: GCCBuiltin<"__builtin_mips_rddsp">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>;
+
+def int_mips_insv: GCCBuiltin<"__builtin_mips_insv">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>;
+def int_mips_bitrev: GCCBuiltin<"__builtin_mips_bitrev">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_packrl_ph: GCCBuiltin<"__builtin_mips_packrl_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+
+def int_mips_repl_qb: GCCBuiltin<"__builtin_mips_repl_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_repl_ph: GCCBuiltin<"__builtin_mips_repl_ph">,
+ Intrinsic<[mips_v2q15_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_pick_qb: GCCBuiltin<"__builtin_mips_pick_qb">,
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrReadMem]>;
+def int_mips_pick_ph: GCCBuiltin<"__builtin_mips_pick_ph">,
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrReadMem]>;
+
+def int_mips_mthlip: GCCBuiltin<"__builtin_mips_mthlip">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+
+def int_mips_bposge32: GCCBuiltin<"__builtin_mips_bposge32">,
+ Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
+
+def int_mips_lbux: GCCBuiltin<"__builtin_mips_lbux">,
+ Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+def int_mips_lhx: GCCBuiltin<"__builtin_mips_lhx">,
+ Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+def int_mips_lwx: GCCBuiltin<"__builtin_mips_lwx">,
+ Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+}
diff --git a/include/llvm/IntrinsicsNVVM.td b/include/llvm/IntrinsicsNVVM.td
new file mode 100644
index 000000000000..1853c9988b47
--- /dev/null
+++ b/include/llvm/IntrinsicsNVVM.td
@@ -0,0 +1,952 @@
+//===- IntrinsicsNVVM.td - Defines NVVM intrinsics ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the NVVM-specific intrinsics for use with NVPTX.
+//
+//===----------------------------------------------------------------------===//
+
+def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
+
+//
+// MISC
+//
+
+ def int_nvvm_clz_i : GCCBuiltin<"__nvvm_clz_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_clz_ll : GCCBuiltin<"__nvvm_clz_ll">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+ def int_nvvm_popc_i : GCCBuiltin<"__nvvm_popc_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_popc_ll : GCCBuiltin<"__nvvm_popc_ll">,
+ Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+ def int_nvvm_prmt : GCCBuiltin<"__nvvm_prmt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Min Max
+//
+
+ def int_nvvm_min_i : GCCBuiltin<"__nvvm_min_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_min_ui : GCCBuiltin<"__nvvm_min_ui">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_min_ll : GCCBuiltin<"__nvvm_min_ll">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_min_ull : GCCBuiltin<"__nvvm_min_ull">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_max_i : GCCBuiltin<"__nvvm_max_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_max_ui : GCCBuiltin<"__nvvm_max_ui">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_max_ll : GCCBuiltin<"__nvvm_max_ll">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_max_ull : GCCBuiltin<"__nvvm_max_ull">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_fmin_f : GCCBuiltin<"__nvvm_fmin_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fmin_ftz_f : GCCBuiltin<"__nvvm_fmin_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_fmax_f : GCCBuiltin<"__nvvm_fmax_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty]
+ , [IntrNoMem, Commutative]>;
+ def int_nvvm_fmax_ftz_f : GCCBuiltin<"__nvvm_fmax_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_fmin_d : GCCBuiltin<"__nvvm_fmin_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fmax_d : GCCBuiltin<"__nvvm_fmax_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Multiplication
+//
+
+ def int_nvvm_mulhi_i : GCCBuiltin<"__nvvm_mulhi_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mulhi_ui : GCCBuiltin<"__nvvm_mulhi_ui">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_mulhi_ll : GCCBuiltin<"__nvvm_mulhi_ll">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mulhi_ull : GCCBuiltin<"__nvvm_mulhi_ull">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_mul_rn_ftz_f : GCCBuiltin<"__nvvm_mul_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rn_f : GCCBuiltin<"__nvvm_mul_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rz_ftz_f : GCCBuiltin<"__nvvm_mul_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rz_f : GCCBuiltin<"__nvvm_mul_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rm_ftz_f : GCCBuiltin<"__nvvm_mul_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rm_f : GCCBuiltin<"__nvvm_mul_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rp_ftz_f : GCCBuiltin<"__nvvm_mul_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rp_f : GCCBuiltin<"__nvvm_mul_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_mul_rn_d : GCCBuiltin<"__nvvm_mul_rn_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rz_d : GCCBuiltin<"__nvvm_mul_rz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rm_d : GCCBuiltin<"__nvvm_mul_rm_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul_rp_d : GCCBuiltin<"__nvvm_mul_rp_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_mul24_i : GCCBuiltin<"__nvvm_mul24_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_mul24_ui : GCCBuiltin<"__nvvm_mul24_ui">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Div
+//
+
+ def int_nvvm_div_approx_ftz_f : GCCBuiltin<"__nvvm_div_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_approx_f : GCCBuiltin<"__nvvm_div_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_div_rn_ftz_f : GCCBuiltin<"__nvvm_div_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rn_f : GCCBuiltin<"__nvvm_div_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_div_rz_ftz_f : GCCBuiltin<"__nvvm_div_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rz_f : GCCBuiltin<"__nvvm_div_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_div_rm_ftz_f : GCCBuiltin<"__nvvm_div_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rm_f : GCCBuiltin<"__nvvm_div_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_div_rp_ftz_f : GCCBuiltin<"__nvvm_div_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rp_f : GCCBuiltin<"__nvvm_div_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_div_rn_d : GCCBuiltin<"__nvvm_div_rn_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rz_d : GCCBuiltin<"__nvvm_div_rz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rm_d : GCCBuiltin<"__nvvm_div_rm_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_div_rp_d : GCCBuiltin<"__nvvm_div_rp_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Brev
+//
+
+ def int_nvvm_brev32 : GCCBuiltin<"__nvvm_brev32">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_brev64 : GCCBuiltin<"__nvvm_brev64">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+//
+// Sad
+//
+
+ def int_nvvm_sad_i : GCCBuiltin<"__nvvm_sad_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_sad_ui : GCCBuiltin<"__nvvm_sad_ui">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Floor Ceil
+//
+
+ def int_nvvm_floor_ftz_f : GCCBuiltin<"__nvvm_floor_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_floor_f : GCCBuiltin<"__nvvm_floor_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_floor_d : GCCBuiltin<"__nvvm_floor_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_ceil_ftz_f : GCCBuiltin<"__nvvm_ceil_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_ceil_f : GCCBuiltin<"__nvvm_ceil_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_ceil_d : GCCBuiltin<"__nvvm_ceil_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Abs
+//
+
+ def int_nvvm_abs_i : GCCBuiltin<"__nvvm_abs_i">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_abs_ll : GCCBuiltin<"__nvvm_abs_ll">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+ def int_nvvm_fabs_ftz_f : GCCBuiltin<"__nvvm_fabs_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_fabs_f : GCCBuiltin<"__nvvm_fabs_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_fabs_d : GCCBuiltin<"__nvvm_fabs_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Round
+//
+
+ def int_nvvm_round_ftz_f : GCCBuiltin<"__nvvm_round_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_round_f : GCCBuiltin<"__nvvm_round_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_round_d : GCCBuiltin<"__nvvm_round_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Trunc
+//
+
+ def int_nvvm_trunc_ftz_f : GCCBuiltin<"__nvvm_trunc_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_trunc_f : GCCBuiltin<"__nvvm_trunc_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_trunc_d : GCCBuiltin<"__nvvm_trunc_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Saturate
+//
+
+ def int_nvvm_saturate_ftz_f : GCCBuiltin<"__nvvm_saturate_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_saturate_f : GCCBuiltin<"__nvvm_saturate_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_saturate_d : GCCBuiltin<"__nvvm_saturate_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Exp2 Log2
+//
+
+ def int_nvvm_ex2_approx_ftz_f : GCCBuiltin<"__nvvm_ex2_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_ex2_approx_f : GCCBuiltin<"__nvvm_ex2_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_ex2_approx_d : GCCBuiltin<"__nvvm_ex2_approx_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_lg2_approx_ftz_f : GCCBuiltin<"__nvvm_lg2_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_lg2_approx_f : GCCBuiltin<"__nvvm_lg2_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_lg2_approx_d : GCCBuiltin<"__nvvm_lg2_approx_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Sin Cos
+//
+
+ def int_nvvm_sin_approx_ftz_f : GCCBuiltin<"__nvvm_sin_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sin_approx_f : GCCBuiltin<"__nvvm_sin_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_cos_approx_ftz_f : GCCBuiltin<"__nvvm_cos_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_cos_approx_f : GCCBuiltin<"__nvvm_cos_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+//
+// Fma
+//
+
+ def int_nvvm_fma_rn_ftz_f : GCCBuiltin<"__nvvm_fma_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rn_f : GCCBuiltin<"__nvvm_fma_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rz_ftz_f : GCCBuiltin<"__nvvm_fma_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rz_f : GCCBuiltin<"__nvvm_fma_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rm_ftz_f : GCCBuiltin<"__nvvm_fma_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rm_f : GCCBuiltin<"__nvvm_fma_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rp_ftz_f : GCCBuiltin<"__nvvm_fma_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rp_f : GCCBuiltin<"__nvvm_fma_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_fma_rn_d : GCCBuiltin<"__nvvm_fma_rn_d">,
+ Intrinsic<[llvm_double_ty],
+ [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rz_d : GCCBuiltin<"__nvvm_fma_rz_d">,
+ Intrinsic<[llvm_double_ty],
+ [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rm_d : GCCBuiltin<"__nvvm_fma_rm_d">,
+ Intrinsic<[llvm_double_ty],
+ [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_fma_rp_d : GCCBuiltin<"__nvvm_fma_rp_d">,
+ Intrinsic<[llvm_double_ty],
+ [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Rcp
+//
+
+ def int_nvvm_rcp_rn_ftz_f : GCCBuiltin<"__nvvm_rcp_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rn_f : GCCBuiltin<"__nvvm_rcp_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rz_ftz_f : GCCBuiltin<"__nvvm_rcp_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rz_f : GCCBuiltin<"__nvvm_rcp_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rm_ftz_f : GCCBuiltin<"__nvvm_rcp_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rm_f : GCCBuiltin<"__nvvm_rcp_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rp_ftz_f : GCCBuiltin<"__nvvm_rcp_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rp_f : GCCBuiltin<"__nvvm_rcp_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_rcp_rn_d : GCCBuiltin<"__nvvm_rcp_rn_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rz_d : GCCBuiltin<"__nvvm_rcp_rz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rm_d : GCCBuiltin<"__nvvm_rcp_rm_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_rcp_rp_d : GCCBuiltin<"__nvvm_rcp_rp_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_rcp_approx_ftz_d : GCCBuiltin<"__nvvm_rcp_approx_ftz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Sqrt
+//
+
+ def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rz_ftz_f : GCCBuiltin<"__nvvm_sqrt_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rz_f : GCCBuiltin<"__nvvm_sqrt_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rm_ftz_f : GCCBuiltin<"__nvvm_sqrt_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rm_f : GCCBuiltin<"__nvvm_sqrt_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rp_ftz_f : GCCBuiltin<"__nvvm_sqrt_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rp_f : GCCBuiltin<"__nvvm_sqrt_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_approx_ftz_f : GCCBuiltin<"__nvvm_sqrt_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_approx_f : GCCBuiltin<"__nvvm_sqrt_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_sqrt_rn_d : GCCBuiltin<"__nvvm_sqrt_rn_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rz_d : GCCBuiltin<"__nvvm_sqrt_rz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rm_d : GCCBuiltin<"__nvvm_sqrt_rm_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_sqrt_rp_d : GCCBuiltin<"__nvvm_sqrt_rp_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Rsqrt
+//
+
+ def int_nvvm_rsqrt_approx_ftz_f : GCCBuiltin<"__nvvm_rsqrt_approx_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rsqrt_approx_f : GCCBuiltin<"__nvvm_rsqrt_approx_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_rsqrt_approx_d : GCCBuiltin<"__nvvm_rsqrt_approx_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Add
+//
+
+ def int_nvvm_add_rn_ftz_f : GCCBuiltin<"__nvvm_add_rn_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rn_f : GCCBuiltin<"__nvvm_add_rn_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rz_ftz_f : GCCBuiltin<"__nvvm_add_rz_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rz_f : GCCBuiltin<"__nvvm_add_rz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rm_ftz_f : GCCBuiltin<"__nvvm_add_rm_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rm_f : GCCBuiltin<"__nvvm_add_rm_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rp_ftz_f : GCCBuiltin<"__nvvm_add_rp_ftz_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rp_f : GCCBuiltin<"__nvvm_add_rp_f">,
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_add_rn_d : GCCBuiltin<"__nvvm_add_rn_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rz_d : GCCBuiltin<"__nvvm_add_rz_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rm_d : GCCBuiltin<"__nvvm_add_rm_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+ def int_nvvm_add_rp_d : GCCBuiltin<"__nvvm_add_rp_d">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Commutative]>;
+
+//
+// Convert
+//
+
+ def int_nvvm_d2f_rn_ftz : GCCBuiltin<"__nvvm_d2f_rn_ftz">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rn : GCCBuiltin<"__nvvm_d2f_rn">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rz_ftz : GCCBuiltin<"__nvvm_d2f_rz_ftz">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rz : GCCBuiltin<"__nvvm_d2f_rz">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rm_ftz : GCCBuiltin<"__nvvm_d2f_rm_ftz">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rm : GCCBuiltin<"__nvvm_d2f_rm">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rp_ftz : GCCBuiltin<"__nvvm_d2f_rp_ftz">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2f_rp : GCCBuiltin<"__nvvm_d2f_rp">,
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_d2i_rn : GCCBuiltin<"__nvvm_d2i_rn">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2i_rz : GCCBuiltin<"__nvvm_d2i_rz">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2i_rm : GCCBuiltin<"__nvvm_d2i_rm">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2i_rp : GCCBuiltin<"__nvvm_d2i_rp">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_d2ui_rn : GCCBuiltin<"__nvvm_d2ui_rn">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ui_rz : GCCBuiltin<"__nvvm_d2ui_rz">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ui_rm : GCCBuiltin<"__nvvm_d2ui_rm">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ui_rp : GCCBuiltin<"__nvvm_d2ui_rp">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_i2d_rn : GCCBuiltin<"__nvvm_i2d_rn">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2d_rz : GCCBuiltin<"__nvvm_i2d_rz">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2d_rm : GCCBuiltin<"__nvvm_i2d_rm">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2d_rp : GCCBuiltin<"__nvvm_i2d_rp">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ def int_nvvm_ui2d_rn : GCCBuiltin<"__nvvm_ui2d_rn">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2d_rz : GCCBuiltin<"__nvvm_ui2d_rz">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2d_rm : GCCBuiltin<"__nvvm_ui2d_rm">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2d_rp : GCCBuiltin<"__nvvm_ui2d_rp">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ def int_nvvm_f2i_rn_ftz : GCCBuiltin<"__nvvm_f2i_rn_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rn : GCCBuiltin<"__nvvm_f2i_rn">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rz_ftz : GCCBuiltin<"__nvvm_f2i_rz_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rz : GCCBuiltin<"__nvvm_f2i_rz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rm_ftz : GCCBuiltin<"__nvvm_f2i_rm_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rm : GCCBuiltin<"__nvvm_f2i_rm">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rp_ftz : GCCBuiltin<"__nvvm_f2i_rp_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2i_rp : GCCBuiltin<"__nvvm_f2i_rp">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_f2ui_rn_ftz : GCCBuiltin<"__nvvm_f2ui_rn_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rn : GCCBuiltin<"__nvvm_f2ui_rn">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rz_ftz : GCCBuiltin<"__nvvm_f2ui_rz_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rz : GCCBuiltin<"__nvvm_f2ui_rz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rm_ftz : GCCBuiltin<"__nvvm_f2ui_rm_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rm : GCCBuiltin<"__nvvm_f2ui_rm">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rp_ftz : GCCBuiltin<"__nvvm_f2ui_rp_ftz">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ui_rp : GCCBuiltin<"__nvvm_f2ui_rp">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_i2f_rn : GCCBuiltin<"__nvvm_i2f_rn">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2f_rz : GCCBuiltin<"__nvvm_i2f_rz">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2f_rm : GCCBuiltin<"__nvvm_i2f_rm">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_i2f_rp : GCCBuiltin<"__nvvm_i2f_rp">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ def int_nvvm_ui2f_rn : GCCBuiltin<"__nvvm_ui2f_rn">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2f_rz : GCCBuiltin<"__nvvm_ui2f_rz">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2f_rm : GCCBuiltin<"__nvvm_ui2f_rm">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_nvvm_ui2f_rp : GCCBuiltin<"__nvvm_ui2f_rp">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ def int_nvvm_lohi_i2d : GCCBuiltin<"__nvvm_lohi_i2d">,
+ Intrinsic<[llvm_double_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+
+ def int_nvvm_d2i_lo : GCCBuiltin<"__nvvm_d2i_lo">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2i_hi : GCCBuiltin<"__nvvm_d2i_hi">,
+ Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_f2ll_rn_ftz : GCCBuiltin<"__nvvm_f2ll_rn_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rn : GCCBuiltin<"__nvvm_f2ll_rn">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rz_ftz : GCCBuiltin<"__nvvm_f2ll_rz_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rz : GCCBuiltin<"__nvvm_f2ll_rz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rm_ftz : GCCBuiltin<"__nvvm_f2ll_rm_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rm : GCCBuiltin<"__nvvm_f2ll_rm">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rp_ftz : GCCBuiltin<"__nvvm_f2ll_rp_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ll_rp : GCCBuiltin<"__nvvm_f2ll_rp">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_f2ull_rn_ftz : GCCBuiltin<"__nvvm_f2ull_rn_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rn : GCCBuiltin<"__nvvm_f2ull_rn">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rz_ftz : GCCBuiltin<"__nvvm_f2ull_rz_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rz : GCCBuiltin<"__nvvm_f2ull_rz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rm_ftz : GCCBuiltin<"__nvvm_f2ull_rm_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rm : GCCBuiltin<"__nvvm_f2ull_rm">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rp_ftz : GCCBuiltin<"__nvvm_f2ull_rp_ftz">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2ull_rp : GCCBuiltin<"__nvvm_f2ull_rp">,
+ Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_d2ll_rn : GCCBuiltin<"__nvvm_d2ll_rn">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ll_rz : GCCBuiltin<"__nvvm_d2ll_rz">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ll_rm : GCCBuiltin<"__nvvm_d2ll_rm">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ll_rp : GCCBuiltin<"__nvvm_d2ll_rp">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_d2ull_rn : GCCBuiltin<"__nvvm_d2ull_rn">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ull_rz : GCCBuiltin<"__nvvm_d2ull_rz">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ull_rm : GCCBuiltin<"__nvvm_d2ull_rm">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+ def int_nvvm_d2ull_rp : GCCBuiltin<"__nvvm_d2ull_rp">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+ def int_nvvm_ll2f_rn : GCCBuiltin<"__nvvm_ll2f_rn">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2f_rz : GCCBuiltin<"__nvvm_ll2f_rz">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2f_rm : GCCBuiltin<"__nvvm_ll2f_rm">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2f_rp : GCCBuiltin<"__nvvm_ll2f_rp">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2f_rn : GCCBuiltin<"__nvvm_ull2f_rn">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2f_rz : GCCBuiltin<"__nvvm_ull2f_rz">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2f_rm : GCCBuiltin<"__nvvm_ull2f_rm">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2f_rp : GCCBuiltin<"__nvvm_ull2f_rp">,
+ Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+ def int_nvvm_ll2d_rn : GCCBuiltin<"__nvvm_ll2d_rn">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2d_rz : GCCBuiltin<"__nvvm_ll2d_rz">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2d_rm : GCCBuiltin<"__nvvm_ll2d_rm">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ll2d_rp : GCCBuiltin<"__nvvm_ll2d_rp">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2d_rn : GCCBuiltin<"__nvvm_ull2d_rn">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2d_rz : GCCBuiltin<"__nvvm_ull2d_rz">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2d_rm : GCCBuiltin<"__nvvm_ull2d_rm">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_ull2d_rp : GCCBuiltin<"__nvvm_ull2d_rp">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+ def int_nvvm_f2h_rn_ftz : GCCBuiltin<"__nvvm_f2h_rn_ftz">,
+ Intrinsic<[llvm_i16_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_f2h_rn : GCCBuiltin<"__nvvm_f2h_rn">,
+ Intrinsic<[llvm_i16_ty], [llvm_float_ty], [IntrNoMem]>;
+
+ def int_nvvm_h2f : GCCBuiltin<"__nvvm_h2f">,
+ Intrinsic<[llvm_float_ty], [llvm_i16_ty], [IntrNoMem]>;
+
+//
+// Bitcast
+//
+
+ def int_nvvm_bitcast_f2i : GCCBuiltin<"__nvvm_bitcast_f2i">,
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_nvvm_bitcast_i2f : GCCBuiltin<"__nvvm_bitcast_i2f">,
+ Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ def int_nvvm_bitcast_ll2d : GCCBuiltin<"__nvvm_bitcast_ll2d">,
+ Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_nvvm_bitcast_d2ll : GCCBuiltin<"__nvvm_bitcast_d2ll">,
+ Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+
+// Atomic not available as an llvm intrinsic.
+ def int_nvvm_atomic_load_add_f32 : Intrinsic<[llvm_float_ty],
+ [LLVMAnyPointerType<llvm_float_ty>, llvm_float_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+ def int_nvvm_atomic_load_inc_32 : Intrinsic<[llvm_i32_ty],
+ [LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+ def int_nvvm_atomic_load_dec_32 : Intrinsic<[llvm_i32_ty],
+ [LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+
+// Bar.Sync
+ def int_cuda_syncthreads : GCCBuiltin<"__syncthreads">,
+ Intrinsic<[], [], []>;
+ def int_nvvm_barrier0 : GCCBuiltin<"__nvvm_bar0">,
+ Intrinsic<[], [], []>;
+ def int_nvvm_barrier0_popc : GCCBuiltin<"__nvvm_bar0_popc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+ def int_nvvm_barrier0_and : GCCBuiltin<"__nvvm_bar0_and">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+ def int_nvvm_barrier0_or : GCCBuiltin<"__nvvm_bar0_or">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+ // Membar
+ def int_nvvm_membar_cta : GCCBuiltin<"__nvvm_membar_cta">,
+ Intrinsic<[], [], []>;
+ def int_nvvm_membar_gl : GCCBuiltin<"__nvvm_membar_gl">,
+ Intrinsic<[], [], []>;
+ def int_nvvm_membar_sys : GCCBuiltin<"__nvvm_membar_sys">,
+ Intrinsic<[], [], []>;
+
+
+// Accessing special registers
+ def int_nvvm_read_ptx_sreg_tid_x :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_tid_x">;
+ def int_nvvm_read_ptx_sreg_tid_y :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_tid_y">;
+ def int_nvvm_read_ptx_sreg_tid_z :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_tid_z">;
+
+ def int_nvvm_read_ptx_sreg_ntid_x :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_x">;
+ def int_nvvm_read_ptx_sreg_ntid_y :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_y">;
+ def int_nvvm_read_ptx_sreg_ntid_z :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_z">;
+
+ def int_nvvm_read_ptx_sreg_ctaid_x :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_x">;
+ def int_nvvm_read_ptx_sreg_ctaid_y :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_y">;
+ def int_nvvm_read_ptx_sreg_ctaid_z :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_z">;
+
+ def int_nvvm_read_ptx_sreg_nctaid_x :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_x">;
+ def int_nvvm_read_ptx_sreg_nctaid_y :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_y">;
+ def int_nvvm_read_ptx_sreg_nctaid_z :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_z">;
+
+ def int_nvvm_read_ptx_sreg_warpsize :
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_warpsize">;
+
+
+// Generated within nvvm. Use for ldu on sm_20 or later
+// @TODO: Revisit this, Changed LLVMAnyPointerType to LLVMPointerType
+def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldu.global.i">;
+def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldu.global.f">;
+def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldu.global.p">;
+
+
+// Use for generic pointers
+// - These intrinsics are used to convert address spaces.
+// - The input pointer and output pointer must have the same type, except for
+// the address-space. (This restriction is not enforced here as there is
+// currently no way to describe it).
+// - 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
+// the same.
+def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.local.to.gen">;
+def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.shared.to.gen">;
+def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.global.to.gen">;
+def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.constant.to.gen">;
+
+def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.gen.to.global">;
+def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.gen.to.shared">;
+def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.gen.to.local">;
+def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty],
+ [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.gen.to.constant">;
+
+// Used in nvvm internally to help address space opt and ptx code generation
+// 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],
+ [llvm_anyptr_ty],
+ [IntrNoMem, NoCapture<0>],
+ "llvm.nvvm.ptr.gen.to.param">;
+
+// Move intrinsics, used in nvvm internally
+
+def int_nvvm_move_i8 : Intrinsic<[llvm_i8_ty], [llvm_i8_ty], [IntrNoMem],
+ "llvm.nvvm.move.i8">;
+def int_nvvm_move_i16 : Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem],
+ "llvm.nvvm.move.i16">;
+def int_nvvm_move_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem],
+ "llvm.nvvm.move.i32">;
+def int_nvvm_move_i64 : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem],
+ "llvm.nvvm.move.i64">;
+def int_nvvm_move_float : Intrinsic<[llvm_float_ty], [llvm_float_ty],
+ [IntrNoMem], "llvm.nvvm.move.float">;
+def int_nvvm_move_double : Intrinsic<[llvm_double_ty], [llvm_double_ty],
+ [IntrNoMem], "llvm.nvvm.move.double">;
+def int_nvvm_move_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty],
+ [IntrNoMem, NoCapture<0>], "llvm.nvvm.move.ptr">;
+
+
+/// Error / Warn
+def int_nvvm_compiler_error :
+ Intrinsic<[], [llvm_anyptr_ty], [], "llvm.nvvm.compiler.error">;
+def int_nvvm_compiler_warn :
+ Intrinsic<[], [llvm_anyptr_ty], [], "llvm.nvvm.compiler.warn">;
+
+
+// Old PTX back-end intrinsics retained here for backwards-compatibility
+
+multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> {
+// FIXME: Do we need the 128-bit integer type version?
+// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>;
+
+// FIXME: Enable this once v4i32 support is enabled in back-end.
+// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>;
+
+ def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_x")>;
+ def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_y")>;
+ def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_z")>;
+ def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_w")>;
+}
+
+class PTXReadSpecialRegisterIntrinsic_r32<string name>
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<name>;
+
+class PTXReadSpecialRegisterIntrinsic_r64<string name>
+ : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>,
+ GCCBuiltin<name>;
+
+defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_tid">;
+defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_ntid">;
+
+def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_laneid">;
+def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_warpid">;
+def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_nwarpid">;
+
+defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_ctaid">;
+defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_nctaid">;
+
+def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_smid">;
+def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_nsmid">;
+def int_ptx_read_gridid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_gridid">;
+
+def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_eq">;
+def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_le">;
+def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_lt">;
+def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_ge">;
+def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_gt">;
+
+def int_ptx_read_clock : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_clock">;
+def int_ptx_read_clock64 : PTXReadSpecialRegisterIntrinsic_r64
+ <"__builtin_ptx_read_clock64">;
+
+def int_ptx_read_pm0 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm0">;
+def int_ptx_read_pm1 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm1">;
+def int_ptx_read_pm2 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm2">;
+def int_ptx_read_pm3 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm3">;
+
+def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>,
+ GCCBuiltin<"__builtin_ptx_bar_sync">;
diff --git a/include/llvm/IntrinsicsPTX.td b/include/llvm/IntrinsicsPTX.td
deleted file mode 100644
index 28379c918dea..000000000000
--- a/include/llvm/IntrinsicsPTX.td
+++ /dev/null
@@ -1,92 +0,0 @@
-//===- IntrinsicsPTX.td - Defines PTX intrinsics -----------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines all of the PTX-specific intrinsics.
-//
-//===----------------------------------------------------------------------===//
-
-let TargetPrefix = "ptx" in {
- multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> {
-// FIXME: Do we need the 128-bit integer type version?
-// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>;
-
-// FIXME: Enable this once v4i32 support is enabled in back-end.
-// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>;
-
- def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
- GCCBuiltin<!strconcat(prefix, "_x")>;
- def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
- GCCBuiltin<!strconcat(prefix, "_y")>;
- def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
- GCCBuiltin<!strconcat(prefix, "_z")>;
- def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
- GCCBuiltin<!strconcat(prefix, "_w")>;
- }
-
- class PTXReadSpecialRegisterIntrinsic_r32<string name>
- : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
- GCCBuiltin<name>;
-
- class PTXReadSpecialRegisterIntrinsic_r64<string name>
- : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>,
- GCCBuiltin<name>;
-}
-
-defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32
- <"__builtin_ptx_read_tid">;
-defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32
- <"__builtin_ptx_read_ntid">;
-
-def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_laneid">;
-def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_warpid">;
-def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_nwarpid">;
-
-defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32
- <"__builtin_ptx_read_ctaid">;
-defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32
- <"__builtin_ptx_read_nctaid">;
-
-def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_smid">;
-def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_nsmid">;
-def int_ptx_read_gridid : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_gridid">;
-
-def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_lanemask_eq">;
-def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_lanemask_le">;
-def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_lanemask_lt">;
-def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_lanemask_ge">;
-def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_lanemask_gt">;
-
-def int_ptx_read_clock : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_clock">;
-def int_ptx_read_clock64 : PTXReadSpecialRegisterIntrinsic_r64
- <"__builtin_ptx_read_clock64">;
-
-def int_ptx_read_pm0 : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_pm0">;
-def int_ptx_read_pm1 : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_pm1">;
-def int_ptx_read_pm2 : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_pm2">;
-def int_ptx_read_pm3 : PTXReadSpecialRegisterIntrinsic_r32
- <"__builtin_ptx_read_pm3">;
-
-let TargetPrefix = "ptx" in
- def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>,
- GCCBuiltin<"__builtin_ptx_bar_sync">;
diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td
index cb7b3eadc870..e8039f23583a 100644
--- a/include/llvm/IntrinsicsX86.td
+++ b/include/llvm/IntrinsicsX86.td
@@ -819,6 +819,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
[IntrNoMem]>;
}
+// PCLMUL instruction
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_pclmulqdq : GCCBuiltin<"__builtin_ia32_pclmulqdq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+}
+
// Vector pack
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_packusdw : GCCBuiltin<"__builtin_ia32_packusdw128">,
@@ -1005,6 +1012,28 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
+// SSE4A
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse4a_extrqi : GCCBuiltin<"__builtin_ia32_extrqi">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse4a_extrq : GCCBuiltin<"__builtin_ia32_extrq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+ def int_x86_sse4a_insertqi : GCCBuiltin<"__builtin_ia32_insertqi">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_i8_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse4a_insertq : GCCBuiltin<"__builtin_ia32_insertq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+ def int_x86_sse4a_movnt_ss : GCCBuiltin<"__builtin_ia32_movntss">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4f32_ty], []>;
+ def int_x86_sse4a_movnt_sd : GCCBuiltin<"__builtin_ia32_movntsd">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v2f64_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
// AVX
// Arithmetic ops
@@ -1272,16 +1301,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[], [llvm_ptr_ty, llvm_v32i8_ty], []>;
}
-// Cacheability support ops
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_movnt_dq_256 : GCCBuiltin<"__builtin_ia32_movntdq256">,
- Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty], []>;
- def int_x86_avx_movnt_pd_256 : GCCBuiltin<"__builtin_ia32_movntpd256">,
- Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], []>;
- def int_x86_avx_movnt_ps_256 : GCCBuiltin<"__builtin_ia32_movntps256">,
- Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], []>;
-}
-
// Conditional load ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_maskload_pd : GCCBuiltin<"__builtin_ia32_maskloadpd">,
@@ -1725,6 +1744,75 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
[IntrNoMem]>;
}
+// Gather ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+
+ def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">,
+ Intrinsic<[llvm_v4i64_ty],
+ [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">,
+ Intrinsic<[llvm_v4i64_ty],
+ [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">,
+ Intrinsic<[llvm_v8i32_ty],
+ [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+ def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty],
+ [IntrReadMem]>;
+}
+
// Misc.
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb256">,
@@ -1740,137 +1828,137 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
-// FMA4
+// FMA3 and FMA4
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_fma4_vfmadd_ss : GCCBuiltin<"__builtin_ia32_vfmaddss">,
+ def int_x86_fma_vfmadd_ss : GCCBuiltin<"__builtin_ia32_vfmaddss">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmadd_sd : GCCBuiltin<"__builtin_ia32_vfmaddsd">,
+ def int_x86_fma_vfmadd_sd : GCCBuiltin<"__builtin_ia32_vfmaddsd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmadd_ps : GCCBuiltin<"__builtin_ia32_vfmaddps">,
+ def int_x86_fma_vfmadd_ps : GCCBuiltin<"__builtin_ia32_vfmaddps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmadd_pd : GCCBuiltin<"__builtin_ia32_vfmaddpd">,
+ def int_x86_fma_vfmadd_pd : GCCBuiltin<"__builtin_ia32_vfmaddpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256">,
+ def int_x86_fma_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256">,
+ def int_x86_fma_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_ss : GCCBuiltin<"__builtin_ia32_vfmsubss">,
+ def int_x86_fma_vfmsub_ss : GCCBuiltin<"__builtin_ia32_vfmsubss">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_sd : GCCBuiltin<"__builtin_ia32_vfmsubsd">,
+ def int_x86_fma_vfmsub_sd : GCCBuiltin<"__builtin_ia32_vfmsubsd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_ps : GCCBuiltin<"__builtin_ia32_vfmsubps">,
+ def int_x86_fma_vfmsub_ps : GCCBuiltin<"__builtin_ia32_vfmsubps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_pd : GCCBuiltin<"__builtin_ia32_vfmsubpd">,
+ def int_x86_fma_vfmsub_pd : GCCBuiltin<"__builtin_ia32_vfmsubpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubps256">,
+ def int_x86_fma_vfmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubpd256">,
+ def int_x86_fma_vfmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_ss : GCCBuiltin<"__builtin_ia32_vfnmaddss">,
+ def int_x86_fma_vfnmadd_ss : GCCBuiltin<"__builtin_ia32_vfnmaddss">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_sd : GCCBuiltin<"__builtin_ia32_vfnmaddsd">,
+ def int_x86_fma_vfnmadd_sd : GCCBuiltin<"__builtin_ia32_vfnmaddsd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_ps : GCCBuiltin<"__builtin_ia32_vfnmaddps">,
+ def int_x86_fma_vfnmadd_ps : GCCBuiltin<"__builtin_ia32_vfnmaddps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_pd : GCCBuiltin<"__builtin_ia32_vfnmaddpd">,
+ def int_x86_fma_vfnmadd_pd : GCCBuiltin<"__builtin_ia32_vfnmaddpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmaddps256">,
+ def int_x86_fma_vfnmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmaddps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmaddpd256">,
+ def int_x86_fma_vfnmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmaddpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_ss : GCCBuiltin<"__builtin_ia32_vfnmsubss">,
+ def int_x86_fma_vfnmsub_ss : GCCBuiltin<"__builtin_ia32_vfnmsubss">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_sd : GCCBuiltin<"__builtin_ia32_vfnmsubsd">,
+ def int_x86_fma_vfnmsub_sd : GCCBuiltin<"__builtin_ia32_vfnmsubsd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_ps : GCCBuiltin<"__builtin_ia32_vfnmsubps">,
+ def int_x86_fma_vfnmsub_ps : GCCBuiltin<"__builtin_ia32_vfnmsubps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_pd : GCCBuiltin<"__builtin_ia32_vfnmsubpd">,
+ def int_x86_fma_vfnmsub_pd : GCCBuiltin<"__builtin_ia32_vfnmsubpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmsubps256">,
+ def int_x86_fma_vfnmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmsubps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfnmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmsubpd256">,
+ def int_x86_fma_vfnmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmsubpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">,
+ def int_x86_fma_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">,
+ def int_x86_fma_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmaddsub_ps_256 :
+ def int_x86_fma_vfmaddsub_ps_256 :
GCCBuiltin<"__builtin_ia32_vfmaddsubps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmaddsub_pd_256 :
+ def int_x86_fma_vfmaddsub_pd_256 :
GCCBuiltin<"__builtin_ia32_vfmaddsubpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsubadd_ps : GCCBuiltin<"__builtin_ia32_vfmsubaddps">,
+ def int_x86_fma_vfmsubadd_ps : GCCBuiltin<"__builtin_ia32_vfmsubaddps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsubadd_pd : GCCBuiltin<"__builtin_ia32_vfmsubaddpd">,
+ def int_x86_fma_vfmsubadd_pd : GCCBuiltin<"__builtin_ia32_vfmsubaddpd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsubadd_ps_256 :
+ def int_x86_fma_vfmsubadd_ps_256 :
GCCBuiltin<"__builtin_ia32_vfmsubaddps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
[IntrNoMem]>;
- def int_x86_fma4_vfmsubadd_pd_256 :
+ def int_x86_fma_vfmsubadd_pd_256 :
GCCBuiltin<"__builtin_ia32_vfmsubaddpd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
@@ -1901,26 +1989,19 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v8f32_ty, llvm_i8_ty],
[IntrNoMem]>;
- def int_x86_xop_vfrcz_pd :
- GCCBuiltin<"__builtin_ia32_vfrczpd">,
+ def int_x86_xop_vfrcz_pd : GCCBuiltin<"__builtin_ia32_vfrczpd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
- def int_x86_xop_vfrcz_ps :
- GCCBuiltin<"__builtin_ia32_vfrczps">,
+ def int_x86_xop_vfrcz_ps : GCCBuiltin<"__builtin_ia32_vfrczps">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
- def int_x86_xop_vfrcz_sd :
- GCCBuiltin<"__builtin_ia32_vfrczsd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vfrcz_ss :
- GCCBuiltin<"__builtin_ia32_vfrczss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vfrcz_pd_256 :
- GCCBuiltin<"__builtin_ia32_vfrczpd256">,
+ def int_x86_xop_vfrcz_sd : GCCBuiltin<"__builtin_ia32_vfrczsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_xop_vfrcz_ss : GCCBuiltin<"__builtin_ia32_vfrczss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_xop_vfrcz_pd_256 : GCCBuiltin<"__builtin_ia32_vfrczpd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
- def int_x86_xop_vfrcz_ps_256 :
- GCCBuiltin<"__builtin_ia32_vfrczps256">,
+ def int_x86_xop_vfrcz_ps_256 : GCCBuiltin<"__builtin_ia32_vfrczps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
def int_x86_xop_vpcmov :
GCCBuiltin<"__builtin_ia32_vpcmov">,
Intrinsic<[llvm_v2i64_ty],
@@ -1931,262 +2012,32 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty],
[IntrNoMem]>;
- def int_x86_xop_vpcomeqb :
- GCCBuiltin<"__builtin_ia32_vpcomeqb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomeqw :
- GCCBuiltin<"__builtin_ia32_vpcomeqw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomeqd :
- GCCBuiltin<"__builtin_ia32_vpcomeqd">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomeqq :
- GCCBuiltin<"__builtin_ia32_vpcomeqq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomequb :
- GCCBuiltin<"__builtin_ia32_vpcomequb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomequd :
- GCCBuiltin<"__builtin_ia32_vpcomequd">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomequq :
- GCCBuiltin<"__builtin_ia32_vpcomequq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomequw :
- GCCBuiltin<"__builtin_ia32_vpcomequw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseb :
- GCCBuiltin<"__builtin_ia32_vpcomfalseb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalsed :
- GCCBuiltin<"__builtin_ia32_vpcomfalsed">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseq :
- GCCBuiltin<"__builtin_ia32_vpcomfalseq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseub :
- GCCBuiltin<"__builtin_ia32_vpcomfalseub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseud :
- GCCBuiltin<"__builtin_ia32_vpcomfalseud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseuq :
- GCCBuiltin<"__builtin_ia32_vpcomfalseuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalseuw :
- GCCBuiltin<"__builtin_ia32_vpcomfalseuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomfalsew :
- GCCBuiltin<"__builtin_ia32_vpcomfalsew">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeb :
- GCCBuiltin<"__builtin_ia32_vpcomgeb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomged :
- GCCBuiltin<"__builtin_ia32_vpcomged">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeq :
- GCCBuiltin<"__builtin_ia32_vpcomgeq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeub :
- GCCBuiltin<"__builtin_ia32_vpcomgeub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeud :
- GCCBuiltin<"__builtin_ia32_vpcomgeud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeuq :
- GCCBuiltin<"__builtin_ia32_vpcomgeuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgeuw :
- GCCBuiltin<"__builtin_ia32_vpcomgeuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgew :
- GCCBuiltin<"__builtin_ia32_vpcomgew">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtb :
- GCCBuiltin<"__builtin_ia32_vpcomgtb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtd :
- GCCBuiltin<"__builtin_ia32_vpcomgtd">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtq :
- GCCBuiltin<"__builtin_ia32_vpcomgtq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtub :
- GCCBuiltin<"__builtin_ia32_vpcomgtub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtud :
- GCCBuiltin<"__builtin_ia32_vpcomgtud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtuq :
- GCCBuiltin<"__builtin_ia32_vpcomgtuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtuw :
- GCCBuiltin<"__builtin_ia32_vpcomgtuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomgtw :
- GCCBuiltin<"__builtin_ia32_vpcomgtw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleb :
- GCCBuiltin<"__builtin_ia32_vpcomleb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomled :
- GCCBuiltin<"__builtin_ia32_vpcomled">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleq :
- GCCBuiltin<"__builtin_ia32_vpcomleq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleub :
- GCCBuiltin<"__builtin_ia32_vpcomleub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleud :
- GCCBuiltin<"__builtin_ia32_vpcomleud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleuq :
- GCCBuiltin<"__builtin_ia32_vpcomleuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomleuw :
- GCCBuiltin<"__builtin_ia32_vpcomleuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomlew :
- GCCBuiltin<"__builtin_ia32_vpcomlew">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltb :
- GCCBuiltin<"__builtin_ia32_vpcomltb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltd :
- GCCBuiltin<"__builtin_ia32_vpcomltd">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltq :
- GCCBuiltin<"__builtin_ia32_vpcomltq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltub :
- GCCBuiltin<"__builtin_ia32_vpcomltub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltud :
- GCCBuiltin<"__builtin_ia32_vpcomltud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltuq :
- GCCBuiltin<"__builtin_ia32_vpcomltuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltuw :
- GCCBuiltin<"__builtin_ia32_vpcomltuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomltw :
- GCCBuiltin<"__builtin_ia32_vpcomltw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneb :
- GCCBuiltin<"__builtin_ia32_vpcomneb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomned :
- GCCBuiltin<"__builtin_ia32_vpcomned">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneq :
- GCCBuiltin<"__builtin_ia32_vpcomneq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneub :
- GCCBuiltin<"__builtin_ia32_vpcomneub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneud :
- GCCBuiltin<"__builtin_ia32_vpcomneud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneuq :
- GCCBuiltin<"__builtin_ia32_vpcomneuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomneuw :
- GCCBuiltin<"__builtin_ia32_vpcomneuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomnew :
- GCCBuiltin<"__builtin_ia32_vpcomnew">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueb :
- GCCBuiltin<"__builtin_ia32_vpcomtrueb">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrued :
- GCCBuiltin<"__builtin_ia32_vpcomtrued">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueq :
- GCCBuiltin<"__builtin_ia32_vpcomtrueq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueub :
- GCCBuiltin<"__builtin_ia32_vpcomtrueub">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueud :
- GCCBuiltin<"__builtin_ia32_vpcomtrueud">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueuq :
- GCCBuiltin<"__builtin_ia32_vpcomtrueuq">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtrueuw :
- GCCBuiltin<"__builtin_ia32_vpcomtrueuw">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcomtruew :
- GCCBuiltin<"__builtin_ia32_vpcomtruew">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
+
+ def int_x86_xop_vpcomb : GCCBuiltin<"__builtin_ia32_vpcomb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomw : GCCBuiltin<"__builtin_ia32_vpcomw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomd : GCCBuiltin<"__builtin_ia32_vpcomd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomq : GCCBuiltin<"__builtin_ia32_vpcomq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomub : GCCBuiltin<"__builtin_ia32_vpcomub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomuw : GCCBuiltin<"__builtin_ia32_vpcomuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomud : GCCBuiltin<"__builtin_ia32_vpcomud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcomuq : GCCBuiltin<"__builtin_ia32_vpcomuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+
def int_x86_xop_vphaddbd :
GCCBuiltin<"__builtin_ia32_vphaddbd">,
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
@@ -2297,22 +2148,32 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
- def int_x86_xop_vprotb :
- GCCBuiltin<"__builtin_ia32_vprotb">,
+
+ def int_x86_xop_vprotb : GCCBuiltin<"__builtin_ia32_vprotb">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
- def int_x86_xop_vprotd :
- GCCBuiltin<"__builtin_ia32_vprotd">,
+ def int_x86_xop_vprotd : GCCBuiltin<"__builtin_ia32_vprotd">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- def int_x86_xop_vprotq :
- GCCBuiltin<"__builtin_ia32_vprotq">,
+ def int_x86_xop_vprotq : GCCBuiltin<"__builtin_ia32_vprotq">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;
- def int_x86_xop_vprotw :
- GCCBuiltin<"__builtin_ia32_vprotw">,
+ def int_x86_xop_vprotw : GCCBuiltin<"__builtin_ia32_vprotw">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_x86_xop_vprotbi : GCCBuiltin<"__builtin_ia32_vprotbi">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotdi : GCCBuiltin<"__builtin_ia32_vprotdi">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotqi : GCCBuiltin<"__builtin_ia32_vprotqi">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotwi : GCCBuiltin<"__builtin_ia32_vprotwi">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+
def int_x86_xop_vpshab :
GCCBuiltin<"__builtin_ia32_vpshab">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
@@ -2675,3 +2536,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty],
[IntrNoMem]>;
}
+
+//===----------------------------------------------------------------------===//
+// RDRAND intrinsics. Return a random value and whether it is valid.
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // These are declared side-effecting so they don't get eliminated by CSE or
+ // LICM.
+ 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_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
+}
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 2258d45ce90a..697c94c094b0 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -55,6 +55,7 @@ namespace {
(void) llvm::createScalarEvolutionAliasAnalysisPass();
(void) llvm::createTypeBasedAliasAnalysisPass();
(void) llvm::createBlockPlacementPass();
+ (void) llvm::createBoundsCheckingPass();
(void) llvm::createBreakCriticalEdgesPass();
(void) llvm::createCFGSimplificationPass();
(void) llvm::createConstantMergePass();
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h
index 0b9d3f63f677..5b024675cdc8 100644
--- a/include/llvm/MC/EDInstInfo.h
+++ b/include/llvm/MC/EDInstInfo.h
@@ -12,7 +12,7 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
-
+
#define EDIS_MAX_OPERANDS 13
#define EDIS_MAX_SYNTAXES 2
@@ -23,7 +23,7 @@ struct EDInstInfo {
uint8_t operandFlags[EDIS_MAX_OPERANDS];
const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
};
-
+
} // namespace llvm
#endif
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 0f67c993714c..9f5230b9c8fa 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -147,6 +147,11 @@ namespace llvm {
// FIXME: Make this a more general encoding setting?
bool AllowUTF8;
+ /// UseDataRegionDirectives - This is true if data region markers should
+ /// be printed as ".data_region/.end_data_region" directives. If false,
+ /// use "$d/$a" labels instead.
+ bool UseDataRegionDirectives;
+
//===--- Data Emission Directives -------------------------------------===//
/// ZeroDirective - this should be set to the directive used to get some
@@ -172,18 +177,6 @@ namespace llvm {
const char *Data32bitsDirective; // Defaults to "\t.long\t"
const char *Data64bitsDirective; // Defaults to "\t.quad\t"
- /// [Data|Code]Begin - These magic labels are used to marked a region as
- /// data or code, and are used to provide additional information for
- /// correct disassembly on targets that like to mix data and code within
- /// a segment. These labels will be implicitly suffixed by the streamer
- /// to give them unique names.
- const char *DataBegin; // Defaults to "$d."
- const char *CodeBegin; // Defaults to "$a."
- const char *JT8Begin; // Defaults to "$a."
- const char *JT16Begin; // Defaults to "$a."
- const char *JT32Begin; // Defaults to "$a."
- bool SupportsDataRegions;
-
/// GPRel64Directive - if non-null, a directive that is used to emit a word
/// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword
/// on Mips.
@@ -322,26 +315,14 @@ namespace llvm {
/// DwarfSectionOffsetDirective - Special section offset directive.
const char* DwarfSectionOffsetDirective; // Defaults to NULL
- /// DwarfRequiresRelocationForSectionOffset - True if we need to produce a
- /// relocation when we want a section offset in dwarf.
- bool DwarfRequiresRelocationForSectionOffset; // Defaults to true;
-
- /// DwarfUsesLabelOffsetDifference - True if Dwarf2 output can
- /// use EmitLabelOffsetDifference.
- bool DwarfUsesLabelOffsetForRanges;
-
- /// DwarfUsesRelocationsForStringPool - True if this Dwarf output must use
- /// relocations to refer to entries in the string pool.
- bool DwarfUsesRelocationsForStringPool;
+ /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
+ /// uses relocations for references to other .debug_* sections.
+ bool DwarfUsesRelocationsAcrossSections;
/// DwarfRegNumForCFI - True if dwarf register numbers are printed
/// instead of symbolic register names in .cfi_* directives.
bool DwarfRegNumForCFI; // Defaults to false;
- //===--- CBE Asm Translation Table -----------------------------------===//
-
- const char *const *AsmTransCBE; // Defaults to empty
-
//===--- Prologue State ----------------------------------------------===//
std::vector<MachineMove> InitialFrameState;
@@ -388,14 +369,6 @@ namespace llvm {
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; }
- /// [Code|Data]Begin label name accessors.
- const char *getCodeBeginLabelName() const { return CodeBegin; }
- const char *getDataBeginLabelName() const { return DataBegin; }
- const char *getJumpTable8BeginLabelName() const { return JT8Begin; }
- const char *getJumpTable16BeginLabelName() const { return JT16Begin; }
- const char *getJumpTable32BeginLabelName() const { return JT32Begin; }
- bool getSupportsDataRegions() const { return SupportsDataRegions; }
-
/// getNonexecutableStackSection - Targets can implement this method to
/// specify a section to switch to if the translation unit doesn't have any
/// trampolines that require an executable stack.
@@ -492,6 +465,9 @@ namespace llvm {
bool doesAllowUTF8() const {
return AllowUTF8;
}
+ bool doesSupportDataRegionDirectives() const {
+ return UseDataRegionDirectives;
+ }
const char *getZeroDirective() const {
return ZeroDirective;
}
@@ -565,21 +541,12 @@ namespace llvm {
const char *getDwarfSectionOffsetDirective() const {
return DwarfSectionOffsetDirective;
}
- bool doesDwarfRequireRelocationForSectionOffset() const {
- return DwarfRequiresRelocationForSectionOffset;
- }
- bool doesDwarfUseLabelOffsetForRanges() const {
- return DwarfUsesLabelOffsetForRanges;
- }
- bool doesDwarfUseRelocationsForStringPool() const {
- return DwarfUsesRelocationsForStringPool;
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
}
bool useDwarfRegNumForCFI() const {
return DwarfRegNumForCFI;
}
- const char *const *getAsmCBE() const {
- return AsmTransCBE;
- }
void addInitialFrameState(MCSymbol *label, const MachineLocation &D,
const MachineLocation &S) {
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index d139173c3e13..b7b2d663f4cc 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -130,7 +130,7 @@ public:
void addFixup(MCFixup Fixup) {
// Enforce invariant that fixups are in offset order.
- assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) &&
+ assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) &&
"Fixups must be added in order!");
Fixups.push_back(Fixup);
}
@@ -651,6 +651,16 @@ struct IndirectSymbolData {
MCSectionData *SectionData;
};
+// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
+// to one another.
+struct DataRegionData {
+ // This enum should be kept in sync w/ the mach-o definition in
+ // llvm/Object/MachOFormat.h.
+ enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
+ MCSymbol *Start;
+ MCSymbol *End;
+};
+
class MCAssembler {
friend class MCAsmLayout;
@@ -668,6 +678,10 @@ public:
const_indirect_symbol_iterator;
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
+ typedef std::vector<DataRegionData>::const_iterator
+ const_data_region_iterator;
+ typedef std::vector<DataRegionData>::iterator data_region_iterator;
+
private:
MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT
void operator=(const MCAssembler&); // DO NOT IMPLEMENT
@@ -698,6 +712,7 @@ private:
std::vector<IndirectSymbolData> IndirectSymbols;
+ std::vector<DataRegionData> DataRegions;
/// The set of function symbols for which a .thumb_func directive has
/// been seen.
//
@@ -884,6 +899,33 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+ /// @name Data Region List Access
+ /// @{
+
+ // 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 can
+ // disappear.
+ std::vector<DataRegionData> &getDataRegions() {
+ return DataRegions;
+ }
+
+ data_region_iterator data_region_begin() {
+ return DataRegions.begin();
+ }
+ const_data_region_iterator data_region_begin() const {
+ return DataRegions.begin();
+ }
+
+ data_region_iterator data_region_end() {
+ return DataRegions.end();
+ }
+ const_data_region_iterator data_region_end() const {
+ return DataRegions.end();
+ }
+
+ size_t data_region_size() const { return DataRegions.size(); }
+
+ /// @}
/// @name Backend Data Access
/// @{
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index b58631919330..59545d31a655 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -161,6 +161,10 @@ namespace llvm {
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
+ /// getUniqueSymbolID() - Return a unique identifier for use in constructing
+ /// symbol names.
+ unsigned getUniqueSymbolID() { return NextUniqueID++; }
+
/// CreateDirectionalLocalSymbol - Create the definition of a directional
/// local symbol for numbered label (used for "1:" definitions).
MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 9180d1b369fe..0461766c2fd3 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -52,6 +52,14 @@ enum MCAssemblerFlag {
MCAF_Code64 ///< .code64 (X86)
};
+enum MCDataRegionType {
+ MCDR_DataRegion, ///< .data_region
+ MCDR_DataRegionJT8, ///< .data_region jt8
+ MCDR_DataRegionJT16, ///< .data_region jt16
+ MCDR_DataRegionJT32, ///< .data_region jt32
+ MCDR_DataRegionEnd ///< .end_data_region
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 4b5fbec47dce..53a9ce0a3648 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -13,13 +13,13 @@
#include "llvm-c/Disassembler.h"
namespace llvm {
-
+
class MCInst;
class MCSubtargetInfo;
class MemoryObject;
class raw_ostream;
class MCContext;
-
+
struct EDInstInfo;
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
@@ -58,12 +58,12 @@ public:
MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
DisInfo(0), Ctx(0),
STI(STI), CommentStream(0) {}
-
+
virtual ~MCDisassembler();
-
+
/// getInstruction - Returns the disassembly of a single instruction.
///
- /// @param instr - An MCInst to populate with the contents of the
+ /// @param instr - An MCInst to populate with the contents of the
/// instruction.
/// @param size - A value to populate with the size of the instruction, or
/// the number of bytes consumed while attempting to decode
@@ -74,7 +74,7 @@ public:
/// @param vStream - The stream to print warnings and diagnostic messages on.
/// @param cStream - The stream to print comments and annotations on.
/// @return - MCDisassembler::Success if the instruction is valid,
- /// MCDisassembler::SoftFail if the instruction was
+ /// MCDisassembler::SoftFail if the instruction was
/// disassemblable but invalid,
/// MCDisassembler::Fail if the instruction was invalid.
virtual DecodeStatus getInstruction(MCInst& instr,
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index f153cb0c1af0..abbe188fe88d 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -54,11 +54,13 @@ class MCELFObjectTargetWriter {
const uint16_t EMachine;
const unsigned HasRelocationAddend : 1;
const unsigned Is64Bit : 1;
+ const unsigned IsN64 : 1;
protected:
MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
- uint16_t EMachine_, bool HasRelocationAddend_);
+ uint16_t EMachine_, bool HasRelocationAddend,
+ bool IsN64=false);
public:
static uint8_t getOSABI(Triple::OSType OSType) {
@@ -95,7 +97,47 @@ public:
uint16_t getEMachine() { return EMachine; }
bool hasRelocationAddend() { return HasRelocationAddend; }
bool is64Bit() const { return Is64Bit; }
+ bool isN64() const { return IsN64; }
/// @}
+
+ // Instead of changing everyone's API we pack the N64 Type fields
+ // into the existing 32 bit data unsigned.
+#define R_TYPE_SHIFT 0
+#define R_TYPE_MASK 0xffffff00
+#define R_TYPE2_SHIFT 8
+#define R_TYPE2_MASK 0xffff00ff
+#define R_TYPE3_SHIFT 16
+#define R_TYPE3_MASK 0xff00ffff
+#define R_SSYM_SHIFT 24
+#define R_SSYM_MASK 0x00ffffff
+
+ // N64 relocation type accessors
+ unsigned getRType(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
+ }
+ unsigned getRType2(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
+ }
+ unsigned getRType3(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
+ }
+ unsigned getRSsym(uint32_t Type) const {
+ return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
+ }
+
+ // N64 relocation type setting
+ unsigned setRType(unsigned Value, unsigned Type) const {
+ return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
+ }
+ unsigned setRType2(unsigned Value, unsigned Type) const {
+ return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
+ }
+ unsigned setRType3(unsigned Value, unsigned Type) const {
+ return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
+ }
+ unsigned setRSsym(unsigned Value, unsigned Type) const {
+ return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
+ }
};
/// \brief Construct a new ELF writer instance.
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index ff33641dba7f..aa62eb2b16c0 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -176,6 +176,8 @@ public:
VK_PPC_DARWIN_LO16, // lo16(symbol)
VK_PPC_GAS_HA16, // symbol@ha
VK_PPC_GAS_LO16, // symbol@l
+ VK_PPC_TPREL16_HA, // symbol@tprel@ha
+ VK_PPC_TPREL16_LO, // symbol@tprel@l
VK_Mips_GPREL,
VK_Mips_GOT_CALL,
@@ -194,7 +196,9 @@ public:
VK_Mips_GPOFF_LO,
VK_Mips_GOT_DISP,
VK_Mips_GOT_PAGE,
- VK_Mips_GOT_OFST
+ VK_Mips_GOT_OFST,
+ VK_Mips_HIGHER,
+ VK_Mips_HIGHEST
};
private:
diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h
index 1961687146a8..6979ad5807d0 100644
--- a/include/llvm/MC/MCFixupKindInfo.h
+++ b/include/llvm/MC/MCFixupKindInfo.h
@@ -18,7 +18,7 @@ struct MCFixupKindInfo {
/// Is this fixup kind PCrelative? This is used by the assembler backend to
/// evaluate fixup values in a target independent manner when possible.
FKF_IsPCRel = (1 << 0),
-
+
/// Should this fixup kind force a 4-byte aligned effective PC value?
FKF_IsAlignedDownTo32Bits = (1 << 1)
};
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
index e942892da13e..65d1559ac66a 100644
--- a/include/llvm/MC/MCInstrItineraries.h
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -16,6 +16,7 @@
#ifndef LLVM_MC_MCINSTRITINERARIES_H
#define LLVM_MC_MCINSTRITINERARIES_H
+#include "llvm/MC/MCSchedule.h"
#include <algorithm>
namespace llvm {
@@ -95,7 +96,7 @@ struct InstrStage {
/// operands are read and written.
///
struct InstrItinerary {
- unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
+ int NumMicroOps; ///< # of micro-ops, -1 means it's variable
unsigned FirstStage; ///< Index of first stage in itinerary
unsigned LastStage; ///< Index of last + 1 stage in itinerary
unsigned FirstOperandCycle; ///< Index of first operand rd/wr
@@ -109,21 +110,22 @@ struct InstrItinerary {
///
class InstrItineraryData {
public:
+ const MCSchedModel *SchedModel; ///< Basic machine properties.
const InstrStage *Stages; ///< Array of stages selected
const unsigned *OperandCycles; ///< Array of operand cycles selected
const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
const InstrItinerary *Itineraries; ///< Array of itineraries selected
- unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
/// Ctors.
///
- InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
- Itineraries(0), IssueWidth(0) {}
+ InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel),
+ Stages(0), OperandCycles(0),
+ Forwardings(0), Itineraries(0) {}
- InstrItineraryData(const InstrStage *S, const unsigned *OS,
- const unsigned *F, const InstrItinerary *I)
- : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
- IssueWidth(0) {}
+ InstrItineraryData(const MCSchedModel *SM, const InstrStage *S,
+ const unsigned *OS, const unsigned *F)
+ : SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
+ Itineraries(SchedModel->InstrItineraries) {}
/// isEmpty - Returns true if there are no itineraries.
///
@@ -155,15 +157,17 @@ public:
/// class. The latency is the maximum completion time for any stage
/// in the itinerary.
///
+ /// InstrStages override the itinerary's MinLatency property. In fact, if the
+ /// stage latencies, which may be zero, are less than MinLatency,
+ /// getStageLatency returns a value less than MinLatency.
+ ///
+ /// If no stages exist, MinLatency is used. If MinLatency is invalid (<0),
+ /// then it defaults to one cycle.
unsigned getStageLatency(unsigned ItinClassIndx) const {
// If the target doesn't provide itinerary information, use a simple
- // non-zero default value for all instructions. Some target's provide a
- // dummy (Generic) itinerary which should be handled as if it's itinerary is
- // empty. We identify this by looking for a reference to stage zero (invalid
- // stage). This is different from beginStage == endState != 0, which could
- // be used for zero-latency pseudo ops.
- if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
- return 1;
+ // non-zero default value for all instructions.
+ if (isEmpty())
+ return SchedModel->MinLatency < 0 ? 1 : SchedModel->MinLatency;
// Calculate the maximum completion time for any stage.
unsigned Latency = 0, StartCycle = 0;
@@ -238,16 +242,16 @@ public:
return UseCycle;
}
- /// isMicroCoded - Return true if the instructions in the given class decode
- /// to more than one micro-ops.
- bool isMicroCoded(unsigned ItinClassIndx) const {
+ /// getNumMicroOps - Return the number of micro-ops that the given class
+ /// decodes to. Return -1 for classes that require dynamic lookup via
+ /// TargetInstrInfo.
+ int getNumMicroOps(unsigned ItinClassIndx) const {
if (isEmpty())
- return false;
- return Itineraries[ItinClassIndx].NumMicroOps != 1;
+ return 1;
+ return Itineraries[ItinClassIndx].NumMicroOps;
}
};
-
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 9bb598f5468a..949d90700e08 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -179,6 +179,9 @@ public:
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+ void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
+ uint32_t DataSize);
+
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index aea4b410fea2..74e2263c731c 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -22,17 +22,17 @@ namespace llvm {
class StringRef;
class Triple;
-class MCObjectFileInfo {
+class MCObjectFileInfo {
protected:
/// CommDirectiveSupportsAlignment - True if .comm supports alignment. This
/// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't
/// support alignment on comm.
bool CommDirectiveSupportsAlignment;
-
+
/// SupportsWeakEmptyEHFrame - True if target object file supports a
/// weak_definition of constant 0 for an omitted EH frame.
bool SupportsWeakOmittedEHFrame;
-
+
/// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the
/// "EH_frame" symbol for EH information should be an assembler temporary (aka
/// private linkage, aka an L or .L label) or false if it should be a normal
@@ -53,20 +53,20 @@ protected:
/// TextSection - Section directive for standard text.
///
const MCSection *TextSection;
-
+
/// DataSection - Section directive for standard data.
///
const MCSection *DataSection;
-
+
/// BSSSection - Section that is default initialized to zero.
const MCSection *BSSSection;
-
+
/// ReadOnlySection - Section that is readonly and can contain arbitrary
/// initialized data. Targets are not required to have a readonly section.
/// If they don't, various bits of code will fall back to using the data
/// section for constants.
const MCSection *ReadOnlySection;
-
+
/// StaticCtorSection - This section contains the static constructor pointer
/// list.
const MCSection *StaticCtorSection;
@@ -74,7 +74,7 @@ protected:
/// StaticDtorSection - This section contains the static destructor pointer
/// list.
const MCSection *StaticDtorSection;
-
+
/// LSDASection - If exception handling is supported by the target, this is
/// the section the Language Specific Data Area information is emitted to.
const MCSection *LSDASection;
@@ -109,7 +109,7 @@ protected:
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
const MCSection *TLSExtraDataSection;
-
+
/// TLSDataSection - Section directive for Thread Local data.
/// ELF, MachO and COFF.
const MCSection *TLSDataSection; // Defaults to ".tdata".
@@ -141,11 +141,11 @@ protected:
/// Contains the source code name of the variable, visibility and a pointer
/// to the initial value (.tdata or .tbss).
const MCSection *TLSTLVSection; // Defaults to ".tlv".
-
+
/// TLSThreadInitSection - Section for thread local data initialization
/// functions.
const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
-
+
const MCSection *CStringSection;
const MCSection *UStringSection;
const MCSection *TextCoalSection;
@@ -169,7 +169,7 @@ protected:
public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
MCContext &ctx);
-
+
bool isFunctionEHFrameSymbolPrivate() const {
return IsFunctionEHFrameSymbolPrivate;
}
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 6e44e6ceffa3..9591a0094614 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -182,11 +182,6 @@ public:
/// @}
- /// Utility function to encode a SLEB128 value.
- static void EncodeSLEB128(int64_t Value, raw_ostream &OS);
- /// Utility function to encode a ULEB128 value.
- static void EncodeULEB128(uint64_t Value, raw_ostream &OS,
- unsigned Padding = 0);
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 27acf2f2cc21..46a9d71fff24 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -106,10 +106,18 @@ public:
/// of AX.
///
struct MCRegisterDesc {
- const char *Name; // Printable name for the reg (for debugging)
- uint32_t Overlaps; // Overlapping registers, described above
- uint32_t SubRegs; // Sub-register set, described above
- uint32_t SuperRegs; // Super-register set, described above
+ uint32_t Name; // Printable name for the reg (for debugging)
+ uint32_t Overlaps; // Overlapping registers, described above
+ uint32_t SubRegs; // Sub-register set, described above
+ uint32_t SuperRegs; // Super-register set, described above
+
+ // Offset into MCRI::SubRegIndices of a list of sub-register indices for each
+ // sub-register in SubRegs.
+ uint32_t SubRegIndices;
+
+ // RegUnits - Points to the list of register units. The low 4 bits holds the
+ // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
+ uint32_t RegUnits;
};
/// MCRegisterInfo base class - We assume that the target defines a static
@@ -142,10 +150,15 @@ private:
unsigned RAReg; // Return address register
const MCRegisterClass *Classes; // Pointer to the regclass array
unsigned NumClasses; // Number of entries in the array
- const uint16_t *RegLists; // Pointer to the reglists array
+ unsigned NumRegUnits; // Number of regunits.
+ const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
+ const uint16_t *DiffLists; // Pointer to the difflists array
+ const char *RegStrings; // Pointer to the string table.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
unsigned NumSubRegIndices; // Number of subreg indices.
+ const uint16_t *RegEncodingTable; // Pointer to array of register
+ // encodings.
unsigned L2DwarfRegsSize;
unsigned EHL2DwarfRegsSize;
@@ -158,21 +171,83 @@ private:
DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
public:
+ /// DiffListIterator - Base iterator class that can traverse the
+ /// differentially encoded register and regunit lists in DiffLists.
+ /// Don't use this class directly, use one of the specialized sub-classes
+ /// defined below.
+ class DiffListIterator {
+ uint16_t Val;
+ const uint16_t *List;
+
+ protected:
+ /// Create an invalid iterator. Call init() to point to something useful.
+ DiffListIterator() : Val(0), List(0) {}
+
+ /// init - Point the iterator to InitVal, decoding subsequent values from
+ /// DiffList. The iterator will initially point to InitVal, sub-classes are
+ /// responsible for skipping the seed value if it is not part of the list.
+ void init(uint16_t InitVal, const uint16_t *DiffList) {
+ Val = InitVal;
+ List = DiffList;
+ }
+
+ /// advance - Move to the next list position, return the applied
+ /// differential. This function does not detect the end of the list, that
+ /// is the caller's responsibility (by checking for a 0 return value).
+ unsigned advance() {
+ assert(isValid() && "Cannot move off the end of the list.");
+ uint16_t D = *List++;
+ Val += D;
+ return D;
+ }
+
+ public:
+
+ /// isValid - returns true if this iterator is not yet at the end.
+ bool isValid() const { return List; }
+
+ /// Dereference the iterator to get the value at the current position.
+ unsigned operator*() const { return Val; }
+
+ /// Pre-increment to move to the next position.
+ void operator++() {
+ // The end of the list is encoded as a 0 differential.
+ if (!advance())
+ List = 0;
+ }
+ };
+
+ // These iterators are allowed to sub-class DiffListIterator and access
+ // internal list pointers.
+ friend class MCSubRegIterator;
+ friend class MCSuperRegIterator;
+ friend class MCRegAliasIterator;
+ friend class MCRegUnitIterator;
+ friend class MCRegUnitRootIterator;
+
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
const MCRegisterClass *C, unsigned NC,
- const uint16_t *RL,
+ const uint16_t (*RURoots)[2],
+ unsigned NRU,
+ const uint16_t *DL,
+ const char *Strings,
const uint16_t *SubIndices,
- unsigned NumIndices) {
+ unsigned NumIndices,
+ const uint16_t *RET) {
Desc = D;
NumRegs = NR;
RAReg = RA;
Classes = C;
- RegLists = RL;
+ DiffLists = DL;
+ RegStrings = Strings;
NumClasses = NC;
+ RegUnitRoots = RURoots;
+ NumRegUnits = NRU;
SubRegIndices = SubIndices;
NumSubRegIndices = NumIndices;
+ RegEncodingTable = RET;
}
/// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
@@ -231,73 +306,25 @@ public:
return operator[](RegNo);
}
- /// getAliasSet - Return the set of registers aliased by the specified
- /// register, or a null list of there are none. The list returned is zero
- /// terminated.
- ///
- const uint16_t *getAliasSet(unsigned RegNo) const {
- // The Overlaps set always begins with Reg itself.
- return RegLists + get(RegNo).Overlaps + 1;
- }
-
- /// getOverlaps - Return a list of registers that overlap Reg, including
- /// itself. This is the same as the alias set except Reg is included in the
- /// list.
- /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
- ///
- const uint16_t *getOverlaps(unsigned RegNo) const {
- return RegLists + get(RegNo).Overlaps;
- }
-
- /// getSubRegisters - Return the list of registers that are sub-registers of
- /// the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
- ///
- const uint16_t *getSubRegisters(unsigned RegNo) const {
- return RegLists + get(RegNo).SubRegs;
- }
-
/// getSubReg - Returns the physical register number of sub-register "Index"
/// for physical register RegNo. Return zero if the sub-register does not
/// exist.
- unsigned getSubReg(unsigned Reg, unsigned Idx) const {
- return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1);
- }
+ unsigned getSubReg(unsigned Reg, unsigned Idx) const;
/// getMatchingSuperReg - Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
- const MCRegisterClass *RC) const {
- for (const uint16_t *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs)
- if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR))
- return SR;
- return 0;
- }
+ const MCRegisterClass *RC) const;
/// getSubRegIndex - For a given register pair, return the sub-register index
/// if the second register is a sub-register of the first. Return zero
/// otherwise.
- unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {
- for (unsigned I = 1; I <= NumSubRegIndices; ++I)
- if (getSubReg(RegNo, I) == SubRegNo)
- return I;
- return 0;
- }
-
- /// getSuperRegisters - Return the list of registers that are super-registers
- /// of the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
- ///
- const uint16_t *getSuperRegisters(unsigned RegNo) const {
- return RegLists + get(RegNo).SuperRegs;
- }
+ unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
/// getName - Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
- return get(RegNo).Name;
+ return RegStrings + get(RegNo).Name;
}
/// getNumRegs - Return the number of registers this target has (useful for
@@ -306,40 +333,26 @@ public:
return NumRegs;
}
+ /// getNumRegUnits - Return the number of (native) register units in the
+ /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
+ /// can be accessed through MCRegUnitIterator defined below.
+ unsigned getNumRegUnits() const {
+ return NumRegUnits;
+ }
+
/// getDwarfRegNum - Map a target register to an equivalent dwarf register
/// number. Returns -1 if there is no equivalent value. The second
/// parameter allows targets to use different numberings for EH info and
/// debugging info.
- int getDwarfRegNum(unsigned RegNum, bool isEH) const {
- const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
- unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
-
- DwarfLLVMRegPair Key = { RegNum, 0 };
- const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
- if (I == M+Size || I->FromReg != RegNum)
- return -1;
- return I->ToReg;
- }
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const;
/// getLLVMRegNum - Map a dwarf register back to a target register.
///
- int getLLVMRegNum(unsigned RegNum, bool isEH) const {
- const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
- unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
-
- DwarfLLVMRegPair Key = { RegNum, 0 };
- const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
- assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum");
- return I->ToReg;
- }
+ int getLLVMRegNum(unsigned RegNum, bool isEH) const;
/// getSEHRegNum - Map a target register to an equivalent SEH register
/// number. Returns LLVM register number if there is no equivalent value.
- int getSEHRegNum(unsigned RegNum) const {
- const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum);
- if (I == L2SEHRegs.end()) return (int)RegNum;
- return I->second;
- }
+ int getSEHRegNum(unsigned RegNum) const;
regclass_iterator regclass_begin() const { return Classes; }
regclass_iterator regclass_end() const { return Classes+NumClasses; }
@@ -354,6 +367,128 @@ public:
assert(i < getNumRegClasses() && "Register Class ID out of range");
return Classes[i];
}
+
+ /// getEncodingValue - Returns the encoding for RegNo
+ uint16_t getEncodingValue(unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to get encoding for invalid register number!");
+ return RegEncodingTable[RegNo];
+ }
+
+};
+
+//===----------------------------------------------------------------------===//
+// Register List Iterators
+//===----------------------------------------------------------------------===//
+
+// MCRegisterInfo provides lists of super-registers, sub-registers, and
+// aliasing registers. Use these iterator classes to traverse the lists.
+
+/// MCSubRegIterator enumerates all sub-registers of Reg.
+class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs);
+ ++*this;
+ }
+};
+
+/// MCSuperRegIterator enumerates all super-registers of Reg.
+class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
+ ++*this;
+ }
+};
+
+/// MCRegAliasIterator enumerates all registers aliasing Reg.
+/// If IncludeSelf is set, Reg itself is included in the list.
+class MCRegAliasIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+ bool IncludeSelf) {
+ init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps);
+ // Initially, the iterator points to Reg itself.
+ if (!IncludeSelf)
+ ++*this;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Register Units
+//===----------------------------------------------------------------------===//
+
+// 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
+// only if they have a common register unit.
+//
+// A target with a complicated sub-register structure will typically have many
+// fewer register units than actual registers. MCRI::getNumRegUnits() returns
+// the number of register units in the target.
+
+// MCRegUnitIterator enumerates a list of register units for Reg. The list is
+// in ascending numerical order.
+class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ /// MCRegUnitIterator - Create an iterator that traverses the register units
+ /// in Reg.
+ MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ // Decode the RegUnits MCRegisterDesc field.
+ unsigned RU = MCRI->get(Reg).RegUnits;
+ unsigned Scale = RU & 15;
+ unsigned Offset = RU >> 4;
+
+ // Initialize the iterator to Reg * Scale, and the List pointer to
+ // DiffLists + Offset.
+ init(Reg * Scale, MCRI->DiffLists + Offset);
+
+ // That may not be a valid unit, we need to advance by one to get the real
+ // unit number. The first differential can be 0 which would normally
+ // terminate the list, but since we know every register has at least one
+ // unit, we can allow a 0 differential here.
+ advance();
+ }
+};
+
+// Each register unit has one or two root registers. The complete set of
+// registers containing a register unit is the union of the roots and their
+// super-registers. All registers aliasing Unit can be visited like this:
+//
+// for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) {
+// unsigned Root = *RI;
+// visit(Root);
+// for (MCSuperRegIterator SI(Root, MCRI); SI.isValid(); ++SI)
+// visit(*SI);
+// }
+
+/// MCRegUnitRootIterator enumerates the root registers of a register unit.
+class MCRegUnitRootIterator {
+ uint16_t Reg0;
+ uint16_t Reg1;
+public:
+ MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
+ assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
+ Reg0 = MCRI->RegUnitRoots[RegUnit][0];
+ Reg1 = MCRI->RegUnitRoots[RegUnit][1];
+ }
+
+ /// Dereference to get the current root register.
+ unsigned operator*() const {
+ return Reg0;
+ }
+
+ /// isValid - Check if the iterator is at the end of the list.
+ bool isValid() const {
+ return Reg0;
+ }
+
+ /// Preincrement to move to the next root register.
+ void operator++() {
+ assert(isValid() && "Cannot move off the end of the list.");
+ Reg0 = Reg1;
+ Reg1 = 0;
+ }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
new file mode 100644
index 000000000000..3b1cdf1cd2fa
--- /dev/null
+++ b/include/llvm/MC/MCSchedule.h
@@ -0,0 +1,114 @@
+//===-- llvm/MC/MCSchedule.h - Scheduling -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the classes used to describe a subtarget's machine model
+// for scheduling and other instruction cost heuristics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSCHEDMODEL_H
+#define LLVM_MC_MCSCHEDMODEL_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+struct InstrItinerary;
+
+/// Machine model for scheduling, bundling, and heuristics.
+///
+/// The machine model directly provides basic information about the
+/// microarchitecture to the scheduler in the form of properties. It also
+/// optionally refers to scheduler resources tables and itinerary
+/// tables. Scheduler resources tables model the latency and cost for each
+/// instruction type. Itinerary tables are an independant mechanism that
+/// provides a detailed reservation table describing each cycle of instruction
+/// execution. Subtargets may define any or all of the above categories of data
+/// depending on the type of CPU and selected scheduler.
+class MCSchedModel {
+public:
+ static MCSchedModel DefaultSchedModel; // For unknown processors.
+
+ // IssueWidth is the maximum number of instructions that may be scheduled in
+ // the same per-cycle group.
+ unsigned IssueWidth;
+ static const unsigned DefaultIssueWidth = 1;
+
+ // MinLatency is the minimum latency between a register write
+ // followed by a data dependent read. This determines which
+ // instructions may be scheduled in the same per-cycle group. This
+ // is distinct from *expected* latency, which determines the likely
+ // critical path but does not guarantee a pipeline
+ // hazard. MinLatency can always be overridden by the number of
+ // InstrStage cycles.
+ //
+ // (-1) Standard in-order processor.
+ // Use InstrItinerary OperandCycles as MinLatency.
+ // If no OperandCycles exist, then use the cycle of the last InstrStage.
+ //
+ // (0) Out-of-order processor, or in-order with bundled dependencies.
+ // RAW dependencies may be dispatched in the same cycle.
+ // Optional InstrItinerary OperandCycles provides expected latency.
+ //
+ // (>0) In-order processor with variable latencies.
+ // Use the greater of this value or the cycle of the last InstrStage.
+ // Optional InstrItinerary OperandCycles provides expected latency.
+ // TODO: can't yet specify both min and expected latency per operand.
+ int MinLatency;
+ static const unsigned DefaultMinLatency = -1;
+
+ // LoadLatency is the expected latency of load instructions.
+ //
+ // If MinLatency >= 0, this may be overriden for individual load opcodes by
+ // InstrItinerary OperandCycles.
+ unsigned LoadLatency;
+ static const unsigned DefaultLoadLatency = 4;
+
+ // HighLatency is the expected latency of "very high latency" operations.
+ // See TargetInstrInfo::isHighLatencyDef().
+ // By default, this is set to an arbitrarily high number of cycles
+ // likely to have some impact on scheduling heuristics.
+ // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles.
+ unsigned HighLatency;
+ static const unsigned DefaultHighLatency = 10;
+
+ // MispredictPenalty is the typical number of extra cycles the processor
+ // takes to recover from a branch misprediction.
+ unsigned MispredictPenalty;
+ static const unsigned DefaultMispredictPenalty = 10;
+
+private:
+ // TODO: Add a reference to proc resource types and sched resource tables.
+
+ // Instruction itinerary tables used by InstrItineraryData.
+ friend class InstrItineraryData;
+ const InstrItinerary *InstrItineraries;
+
+public:
+ // Default's must be specified as static const literals so that tablegenerated
+ // target code can use it in static initializers. The defaults need to be
+ // initialized in this default ctor because some clients directly instantiate
+ // MCSchedModel instead of using a generated itinerary.
+ MCSchedModel(): IssueWidth(DefaultIssueWidth),
+ MinLatency(DefaultMinLatency),
+ LoadLatency(DefaultLoadLatency),
+ HighLatency(DefaultHighLatency),
+ MispredictPenalty(DefaultMispredictPenalty),
+ InstrItineraries(0) {}
+
+ // Table-gen driven ctor.
+ MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp,
+ const InstrItinerary *ii):
+ IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
+ MispredictPenalty(mp), InstrItineraries(ii){}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 25956008e021..e8c3e59fac8a 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -69,22 +69,7 @@ namespace llvm {
SmallVector<std::pair<const MCSection *,
const MCSection *>, 4> SectionStack;
- unsigned UniqueCodeBeginSuffix;
- unsigned UniqueDataBeginSuffix;
-
protected:
- /// Indicator of whether the previous data-or-code indicator was for
- /// code or not. Used to determine when we need to emit a new indicator.
- enum DataType {
- Data,
- Code,
- JumpTable8,
- JumpTable16,
- JumpTable32
- };
- DataType RegionIndicator;
-
-
MCStreamer(MCContext &Ctx);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
@@ -241,47 +226,15 @@ namespace llvm {
/// used in an assignment.
virtual void EmitLabel(MCSymbol *Symbol);
- /// EmitDataRegion - Emit a label that marks the beginning of a data
- /// region.
- /// On ELF targets, this corresponds to an assembler statement such as:
- /// $d.1:
- virtual void EmitDataRegion();
-
- /// EmitJumpTable8Region - Emit a label that marks the beginning of a
- /// jump table composed of 8-bit offsets.
- /// On ELF targets, this corresponds to an assembler statement such as:
- /// $d.1:
- virtual void EmitJumpTable8Region();
-
- /// EmitJumpTable16Region - Emit a label that marks the beginning of a
- /// jump table composed of 16-bit offsets.
- /// On ELF targets, this corresponds to an assembler statement such as:
- /// $d.1:
- virtual void EmitJumpTable16Region();
-
- /// EmitJumpTable32Region - Emit a label that marks the beginning of a
- /// jump table composed of 32-bit offsets.
- /// On ELF targets, this corresponds to an assembler statement such as:
- /// $d.1:
- virtual void EmitJumpTable32Region();
-
- /// EmitCodeRegion - Emit a label that marks the beginning of a code
- /// region.
- /// On ELF targets, this corresponds to an assembler statement such as:
- /// $a.1:
- virtual void EmitCodeRegion();
-
- /// ForceCodeRegion - Forcibly sets the current region mode to code. Used
- /// at function entry points.
- void ForceCodeRegion() { RegionIndicator = Code; }
-
-
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
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;
+ /// EmitDataRegion - Note in the output the specified region @p Kind.
+ virtual void EmitDataRegion(MCDataRegionType Kind) {}
+
/// EmitThumbFunc - Note in the output that the specified @p Func is
/// a Thumb mode function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func) = 0;
@@ -373,7 +326,7 @@ namespace llvm {
/// @param ByteAlignment - The alignment of the zerofill symbol if
/// non-zero. This must be a power of 2 on some targets.
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0,unsigned ByteAlignment = 0) = 0;
+ uint64_t Size = 0,unsigned ByteAlignment = 0) = 0;
/// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
///
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 3b53f205cd55..31d632de60be 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -30,10 +30,10 @@ class MCSubtargetInfo {
std::string TargetTriple; // Target triple
const SubtargetFeatureKV *ProcFeatures; // Processor feature list
const SubtargetFeatureKV *ProcDesc; // Processor descriptions
- const SubtargetInfoKV *ProcItins; // Scheduling itineraries
- const InstrStage *Stages; // Instruction stages
- const unsigned *OperandCycles; // Operand cycles
- const unsigned *ForwardingPathes; // Forwarding pathes
+ const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model
+ const InstrStage *Stages; // Instruction itinerary stages
+ const unsigned *OperandCycles; // Itinerary operand cycles
+ const unsigned *ForwardingPaths; // Forwarding paths
unsigned NumFeatures; // Number of processor features
unsigned NumProcs; // Number of processors
uint64_t FeatureBits; // Feature bits for current CPU + FS
@@ -42,7 +42,8 @@ public:
void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
- const SubtargetInfoKV *PI, const InstrStage *IS,
+ const SubtargetInfoKV *ProcSched,
+ const InstrStage *IS,
const unsigned *OC, const unsigned *FP,
unsigned NF, unsigned NP);
@@ -69,6 +70,10 @@ public:
/// bits. This version will also change all implied bits.
uint64_t ToggleFeature(StringRef FS);
+ /// getSchedModelForCPU - Get the machine model of a CPU.
+ ///
+ MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
+
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
///
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h
index acb3d4d6144c..f5c8c09df0ea 100644
--- a/include/llvm/MC/MCTargetAsmLexer.h
+++ b/include/llvm/MC/MCTargetAsmLexer.h
@@ -14,72 +14,72 @@
namespace llvm {
class Target;
-
+
/// MCTargetAsmLexer - Generic interface to target specific assembly lexers.
class MCTargetAsmLexer {
/// The current token
AsmToken CurTok;
-
+
/// The location and description of the current error
SMLoc ErrLoc;
std::string Err;
-
+
MCTargetAsmLexer(const MCTargetAsmLexer &); // DO NOT IMPLEMENT
void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
MCTargetAsmLexer(const Target &);
-
+
virtual AsmToken LexToken() = 0;
-
+
void SetError(const SMLoc &errLoc, const std::string &err) {
ErrLoc = errLoc;
Err = err;
}
-
+
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
MCAsmLexer *Lexer;
-
+
public:
virtual ~MCTargetAsmLexer();
-
+
const Target &getTarget() const { return TheTarget; }
-
+
/// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L.
void InstallLexer(MCAsmLexer &L) {
Lexer = &L;
}
-
+
MCAsmLexer *getLexer() {
return Lexer;
}
-
+
/// Lex - Consume the next token from the input stream and return it.
const AsmToken &Lex() {
return CurTok = LexToken();
}
-
+
/// getTok - Get the current (last) lexed token.
const AsmToken &getTok() {
return CurTok;
}
-
+
/// getErrLoc - Get the current error location
const SMLoc &getErrLoc() {
return ErrLoc;
}
-
+
/// getErr - Get the current error string
const std::string &getErr() {
return Err;
}
-
+
/// getKind - Get the kind of current token.
AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
-
+
/// is - Check if the current token has kind \arg K.
bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
-
+
/// isNot - Check if the current token has kind \arg K.
bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
};
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 4e3fd0d3a9ec..929a2042cac6 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -79,6 +79,19 @@ public:
/// \param DirectiveID - the identifier token of the directive.
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
+ /// MatchInstruction - Recognize a series of operands of a parsed instruction
+ /// as an actual MCInst. This returns false on success and returns true on
+ /// failure to match.
+ ///
+ /// On failure, the target parser is responsible for emitting a diagnostic
+ /// explaining the match failure.
+ virtual bool
+ MatchInstruction(SMLoc IDLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ SmallVectorImpl<MCInst> &MCInsts) {
+ return true;
+ }
+
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
/// This returns false on success and returns true on failure to match.
diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h
index 8ddfdbcece49..5caad337f82d 100644
--- a/include/llvm/MC/MachineLocation.h
+++ b/include/llvm/MC/MachineLocation.h
@@ -11,7 +11,7 @@
// from a base address plus an offset. Register indirection can be specified by
// using an offset of zero.
//
-// The MachineMove class is used to represent abstract move operations in the
+// The MachineMove class is used to represent abstract move operations in the
// 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
// frames.
@@ -23,7 +23,7 @@
namespace llvm {
class MCSymbol;
-
+
class MachineLocation {
private:
bool IsRegister; // True if location is a register.
@@ -46,7 +46,7 @@ public:
return IsRegister == Other.IsRegister && Register == Other.Register &&
Offset == Other.Offset;
}
-
+
// Accessors
bool isReg() const { return IsRegister; }
unsigned getReg() const { return Register; }
@@ -77,7 +77,7 @@ private:
/// Label - Symbol for post-instruction address when result of move takes
/// effect.
MCSymbol *Label;
-
+
// Move to & from location.
MachineLocation Destination, Source;
public:
@@ -86,7 +86,7 @@ public:
MachineMove(MCSymbol *label, const MachineLocation &D,
const MachineLocation &S)
: Label(label), Destination(D), Source(S) {}
-
+
// Accessors
MCSymbol *getLabel() const { return Label; }
const MachineLocation &getDestination() const { return Destination; }
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 1a7dc927da49..507d8827750c 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -25,7 +25,7 @@
namespace llvm {
class raw_ostream;
class StringRef;
-
+
//===----------------------------------------------------------------------===//
///
/// SubtargetFeatureKV - Used to provide key value pairs for feature and
@@ -36,13 +36,13 @@ struct SubtargetFeatureKV {
const char *Desc; // Help descriptor
uint64_t Value; // K-V integer value
uint64_t Implies; // K-V bit mask
-
+
// Compare routine for std binary search
bool operator<(const SubtargetFeatureKV &S) const {
return strcmp(Key, S.Key) < 0;
}
};
-
+
//===----------------------------------------------------------------------===//
///
/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
@@ -51,16 +51,16 @@ struct SubtargetFeatureKV {
struct SubtargetInfoKV {
const char *Key; // K-V key string
void *Value; // K-V pointer value
-
+
// Compare routine for std binary search
bool operator<(const SubtargetInfoKV &S) const {
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
/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
/// A comma separates each feature from the next (all lowercase.)
@@ -81,27 +81,27 @@ public:
/// Adding Features.
void AddFeature(const StringRef String, bool IsEnabled = true);
-
+
/// ToggleFeature - Toggle a feature and returns the newly updated feature
/// bits.
uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
-
+
/// Get feature bits of a CPU.
uint64_t getFeatureBits(const StringRef CPU,
const SubtargetFeatureKV *CPUTable,
size_t CPUTableSize,
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
-
+
/// Get scheduling itinerary of a CPU.
void *getItinerary(const StringRef CPU,
const SubtargetInfoKV *Table, size_t TableSize);
-
+
/// Print feature string.
void print(raw_ostream &OS) const;
-
+
// Dump feature info.
void dump() const;
diff --git a/include/llvm/Support/MDBuilder.h b/include/llvm/MDBuilder.h
index 40f028a43274..2aa48b0b4724 100644
--- a/include/llvm/Support/MDBuilder.h
+++ b/include/llvm/MDBuilder.h
@@ -1,4 +1,4 @@
-//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- C++ -*-===//
+//===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_MDBUILDER_H
-#define LLVM_SUPPORT_MDBUILDER_H
+#ifndef LLVM_MDBUILDER_H
+#define LLVM_MDBUILDER_H
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -49,6 +49,29 @@ namespace llvm {
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.
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 73579861ec41..b40549bed6bf 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -165,6 +165,11 @@ public:
static bool classof(const Value *V) {
return V->getValueID() == MDNodeVal;
}
+
+ /// Methods for metadata merging.
+ static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
+ static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
+ static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
private:
// destroy - Delete this node. Only when there are no uses.
void destroy();
diff --git a/include/llvm/Module.h b/include/llvm/Module.h
index b9c98814f159..e6303ac7752d 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/Module.h
@@ -301,10 +301,6 @@ public:
typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*> >
NumeredTypesMapTy;
- /// findUsedStructTypes - Walk the entire module and find all of the
- /// struct types that are in use, returning them in a vector.
- void findUsedStructTypes(std::vector<StructType*> &StructTypes) const;
-
/// getTypeByName - Return the type with the specified name, or null if there
/// is none by that name.
StructType *getTypeByName(StringRef Name) const;
@@ -497,6 +493,13 @@ public:
static iplist<GlobalAlias> Module::*getSublistAccess(GlobalAlias*) {
return &Module::AliasList;
}
+ /// Get the Module's list of named metadata (constant).
+ const NamedMDListType &getNamedMDList() const { return NamedMDList; }
+ /// Get the Module's list of named metadata.
+ NamedMDListType &getNamedMDList() { return NamedMDList; }
+ static ilist<NamedMDNode> Module::*getSublistAccess(NamedMDNode*) {
+ return &Module::NamedMDList;
+ }
/// Get the symbol table of global variable and function identifiers
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers.
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index 77a08d597c4d..befe812a3692 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -90,7 +90,7 @@ public:
/// @brief Create a Binary from Source, autodetecting the file type.
///
-/// @param Source The data to create the Binary from. Ownership is transfered
+/// @param Source The data to create the Binary from. Ownership is transferred
/// to Result if successful. If an error is returned, Source is destroyed
/// by createBinary before returning.
/// @param Result A pointer to the resulting Binary if no error occured.
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index 68b5ca1bc781..967420ec9f12 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -168,6 +168,10 @@ public:
virtual section_iterator begin_sections() const;
virtual section_iterator end_sections() const;
+ const coff_section *getCOFFSection(section_iterator &It) const;
+ const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
+ const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
+
virtual uint8_t getBytesInAddress() const;
virtual StringRef getFileFormatName() const;
virtual unsigned getArch() const;
@@ -184,6 +188,8 @@ public:
return ec;
}
error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
+ ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
+
error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
error_code getSectionContents(const coff_section *Sec,
ArrayRef<uint8_t> &Res) const;
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index e493f5bd9296..7698441fd1cb 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -217,7 +217,7 @@ struct Elf_Verdef_Impl {
}
};
-/// Elf_Verdaux: This is the structure of auxilary data in the SHT_GNU_verdef
+/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template<support::endianness target_endianness, bool is64Bits>
struct Elf_Verdaux_Impl {
@@ -505,9 +505,6 @@ private:
const Elf_Rela *getRela(DataRefImpl Rela) const;
const char *getString(uint32_t section, uint32_t offset) const;
const char *getString(const Elf_Shdr *section, uint32_t offset) const;
- error_code getSymbolName(const Elf_Shdr *section,
- const Elf_Sym *Symb,
- StringRef &Res) const;
error_code getSymbolVersion(const Elf_Shdr *section,
const Elf_Sym *Symb,
StringRef &Version,
@@ -519,6 +516,11 @@ protected:
void validateSymbol(DataRefImpl Symb) const;
public:
+ error_code getSymbolName(const Elf_Shdr *section,
+ const Elf_Sym *Symb,
+ StringRef &Res) const;
+ error_code getSectionName(const Elf_Shdr *section,
+ StringRef &Res) const;
const Elf_Dyn *getDyn(DataRefImpl DynData) const;
error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
bool &IsDefault) const;
@@ -597,11 +599,15 @@ public:
virtual StringRef getObjectType() const { return "ELF"; }
virtual unsigned getArch() const;
virtual StringRef getLoadName() const;
+ virtual error_code getSectionContents(const Elf_Shdr *sec,
+ StringRef &Res) const;
uint64_t getNumSections() const;
uint64_t getStringTableIndex() const;
ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
const Elf_Shdr *getSection(const Elf_Sym *symb) const;
+ const Elf_Shdr *getElfSection(section_iterator &It) const;
+ const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
// Methods for type inquiry through isa, cast, and dyn_cast
bool isDyldType() const { return isDyldELFObject; }
@@ -783,6 +789,21 @@ ELFObjectFile<target_endianness, is64Bits>
}
template<support::endianness target_endianness, bool is64Bits>
+const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
+ELFObjectFile<target_endianness, is64Bits>
+ ::getElfSection(section_iterator &It) const {
+ llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
+ return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
+ELFObjectFile<target_endianness, is64Bits>
+ ::getElfSymbol(symbol_iterator &It) const {
+ return getSymbol(It->getRawDataRefImpl());
+}
+
+template<support::endianness target_endianness, bool is64Bits>
error_code ELFObjectFile<target_endianness, is64Bits>
::getSymbolFileOffset(DataRefImpl Symb,
uint64_t &Result) const {
@@ -1060,6 +1081,15 @@ error_code ELFObjectFile<target_endianness, is64Bits>
template<support::endianness target_endianness, bool is64Bits>
error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionContents(const Elf_Shdr *Sec,
+ StringRef &Result) const {
+ const char *start = (const char*)base() + Sec->sh_offset;
+ Result = StringRef(start, Sec->sh_size);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
::getSectionAlignment(DataRefImpl Sec,
uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1414,6 +1444,98 @@ error_code ELFObjectFile<target_endianness, is64Bits>
res = "Unknown";
}
break;
+ case ELF::EM_HEXAGON:
+ switch (type) {
+ 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_B15_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_HI16);
+ 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_8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_0);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_3);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B32_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_6_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_12_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_11_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_10_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_9_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_7_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_PCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_COPY);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GLOB_DAT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_JMP_SLOT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_RELATIVE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_PLT_B22_PCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPMOD_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_PLT_B22_PCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_PCREL_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32_6_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_16_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_11_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32_6_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_11_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32_6_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_11_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32_6_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_IE_32_6_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_16_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_16_X);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X);
+ default:
+ res = "Unknown";
+ }
+ break;
default:
res = "Unknown";
}
@@ -1489,6 +1611,9 @@ error_code ELFObjectFile<target_endianness, is64Bits>
res = "Unknown";
}
break;
+ case ELF::EM_HEXAGON:
+ res = symname;
+ break;
default:
res = "Unknown";
}
@@ -1888,6 +2013,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits>
return "ELF32-x86-64";
case ELF::EM_ARM:
return "ELF32-arm";
+ case ELF::EM_HEXAGON:
+ return "ELF32-hexagon";
default:
return "ELF32-unknown";
}
@@ -1915,6 +2042,8 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
return Triple::x86_64;
case ELF::EM_ARM:
return Triple::arm;
+ case ELF::EM_HEXAGON:
+ return Triple::hexagon;
default:
return Triple::UnknownArch;
}
@@ -2054,6 +2183,14 @@ error_code ELFObjectFile<target_endianness, is64Bits>
template<support::endianness target_endianness, bool is64Bits>
error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionName(const Elf_Shdr *section,
+ StringRef &Result) const {
+ Result = StringRef(getString(dot_shstrtab_sec, section->sh_name));
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
::getSymbolVersion(const Elf_Shdr *section,
const Elf_Sym *symb,
StringRef &Version,
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
index 089cde92a0a3..f30d431b69da 100644
--- a/include/llvm/Object/MachOFormat.h
+++ b/include/llvm/Object/MachOFormat.h
@@ -97,7 +97,8 @@ namespace macho {
DysymtabLoadCommandSize = 80,
Nlist32Size = 12,
Nlist64Size = 16,
- RelocationInfoSize = 8
+ RelocationInfoSize = 8,
+ LinkeditLoadCommandSize = 16
};
/// \brief Constants for header magic field.
@@ -140,7 +141,8 @@ namespace macho {
LCT_UUID = 0x1b,
LCT_CodeSignature = 0x1d,
LCT_SegmentSplitInfo = 0x1e,
- LCT_FunctionStarts = 0x26
+ LCT_FunctionStarts = 0x26,
+ LCT_DataInCode = 0x29
};
/// \brief Load command structure.
@@ -280,6 +282,18 @@ namespace macho {
};
/// @}
+ /// @name Data-in-code Table Entry
+ /// @{
+
+ // See <mach-o/loader.h>.
+ enum DataRegionType { Data = 1, JumpTable8, JumpTable16, JumpTable32 };
+ struct DataInCodeTableEntry {
+ uint32_t Offset; /* from mach_header to start of data region */
+ uint16_t Length; /* number of bytes in data region */
+ uint16_t Kind; /* a DataRegionType value */
+ };
+
+ /// @}
/// @name Indirect Symbol Table
/// @{
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
index 056040274319..86f150a2940f 100644
--- a/include/llvm/Object/MachOObject.h
+++ b/include/llvm/Object/MachOObject.h
@@ -174,6 +174,9 @@ public:
void ReadSymbol64TableEntry(
uint64_t SymbolTableOffset, unsigned Index,
InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
+ void ReadDataInCodeTableEntry(
+ uint64_t TableOffset, unsigned Index,
+ InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
/// @}
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 4dd7fb581308..2ec656b0124e 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -76,13 +76,13 @@ public:
}
};
-static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
+inline bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
}
-static bool operator <(const DataRefImpl &a, const DataRefImpl &b) {
+inline bool operator <(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
@@ -126,6 +126,8 @@ public:
///
/// This is for display purposes only.
error_code getValueString(SmallVectorImpl<char> &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
};
typedef content_iterator<RelocationRef> relocation_iterator;
@@ -570,6 +572,11 @@ inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
inline error_code RelocationRef::getHidden(bool &Result) const {
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
}
+
+inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
+ return RelocationPimpl;
+}
+
// Inline function definitions.
inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
: LibraryPimpl(LibraryP)
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index fa29f50ccf77..0af58533805e 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -15,6 +15,7 @@
#define LLVM_PASSMANAGERS_H
#include "llvm/Pass.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/DenseMap.h"
@@ -184,7 +185,7 @@ public:
void schedulePass(Pass *P);
/// Set pass P as the last user of the given analysis passes.
- void setLastUser(const SmallVectorImpl<Pass *> &AnalysisPasses, Pass *P);
+ void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P);
/// Collect passes whose last user is P
void collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P);
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index cebfa7982d6d..85607c84482c 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -15,6 +15,9 @@
#ifndef LLVM_SUPPORT_ALIGNOF_H
#define LLVM_SUPPORT_ALIGNOF_H
+#include "llvm/Support/Compiler.h"
+#include <cstddef>
+
namespace llvm {
template <typename T>
@@ -54,7 +57,94 @@ struct AlignOf {
/// class besides some cosmetic cleanliness. Example usage:
/// alignOf<int>() returns the alignment of an int.
template <typename T>
-static inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+
+
+/// \brief Helper for building an aligned character array type.
+///
+/// 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
+/// specialization to cope with old versions of MSVC and GCC where only an
+/// integer literal can be used to specify an alignment constraint. Once built
+/// up here, we can then begin to indirect between these using normal C++
+/// template parameters.
+template <size_t Alignment> struct AlignedCharArrayImpl {};
+template <> struct AlignedCharArrayImpl<0> {
+ typedef char type;
+};
+#if __has_feature(cxx_alignas)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef char alignas(x) type; \
+ }
+#elif defined(__clang__) || defined(__GNUC__)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef char type __attribute__((aligned(x))); \
+ }
+#elif defined(_MSC_VER)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef __declspec(align(x)) char type; \
+ }
+#else
+# error No supported align as directive.
+#endif
+
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
+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);
+// Any larger and MSVC complains.
+#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
+
+/// \brief This class template exposes a typedef for type containing a suitable
+/// aligned character array to hold elements of any of up to four types.
+///
+/// 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, forms
+/// storage suitable to placement new any of these types over. Support for more
+/// than four types can be added at the cost of more boiler plate.
+template <typename T1,
+ typename T2 = char, typename T3 = char, typename T4 = char>
+class AlignedCharArray {
+ class AlignerImpl {
+ T1 t1; T2 t2; T3 t3; T4 t4;
+
+ AlignerImpl(); // Never defined or instantiated.
+ };
+ union SizerImpl {
+ char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
+ };
+
+public:
+ // Sadly, Clang and GCC both fail to align a character array properly even
+ // with an explicit alignment attribute. To work around this, we union
+ // the character array that will actually be used with a struct that contains
+ // a single aligned character member. 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.
+ union union_type {
+ // This is the only member of the union which should be used by clients:
+ char buffer[sizeof(SizerImpl)];
+
+ // This member of the union only exists to force the alignment.
+ struct {
+ typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type
+ nonce_inner_member;
+ } nonce_member;
+ };
+};
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 88c60bac7402..6c2ee08756e7 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -50,6 +50,8 @@ namespace COFF {
};
enum MachineTypes {
+ MT_Invalid = -1,
+
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x13,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
@@ -74,6 +76,8 @@ namespace COFF {
};
enum Characteristics {
+ C_Invalid = 0,
+
/// The file does not contain base relocations and must be loaded at its
/// preferred base. If this cannot be done, the loader will error.
IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
@@ -114,9 +118,9 @@ namespace COFF {
struct symbol {
char Name[NameSize];
uint32_t Value;
+ uint16_t SectionNumber;
uint16_t Type;
uint8_t StorageClass;
- uint16_t SectionNumber;
uint8_t NumberOfAuxSymbols;
};
@@ -138,6 +142,8 @@ namespace COFF {
/// Storage class tells where and what the symbol represents
enum SymbolStorageClass {
+ SSC_Invalid = -1,
+
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
@@ -214,6 +220,8 @@ namespace COFF {
};
enum SectionCharacteristics {
+ SC_Invalid = -1,
+
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
IMAGE_SCN_CNT_CODE = 0x00000020,
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 20634ede7644..c23bb6a97d2e 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -184,6 +184,11 @@ public:
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
+ /// \brief Return true if this function has the given attribute.
+ bool hasFnAttr(Attributes N) const {
+ CALLSITE_DELEGATE_GETTER(hasFnAttr(N));
+ }
+
/// paramHasAttr - whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, Attributes attr) const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index c212d2d59f64..ae1570da9c42 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -217,11 +217,11 @@ public:
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
protected:
- explicit Option(enum NumOccurrencesFlag Occurrences,
+ explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
enum OptionHidden Hidden)
- : NumOccurrences(0), Occurrences(Occurrences), HiddenFlag(Hidden),
- Formatting(NormalFormatting), Position(0),
- AdditionalVals(0), NextRegistered(0),
+ : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
+ HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
+ Position(0), AdditionalVals(0), NextRegistered(0),
ArgStr(""), HelpStr(""), ValueStr("") {
}
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index d0b186ea7c2b..f654f327a923 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -19,6 +19,25 @@
# define __has_feature(x) 0
#endif
+/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references?
+/// This implies that <utility> provides the one-argument std::move; it
+/// does not imply the existence of any other C++ library features.
+#if (__has_feature(cxx_rvalue_references) \
+ || defined(__GXX_EXPERIMENTAL_CXX0X__) \
+ || _MSC_VER >= 1600)
+#define LLVM_USE_RVALUE_REFERENCES 1
+#else
+#define LLVM_USE_RVALUE_REFERENCES 0
+#endif
+
+/// llvm_move - Expands to ::std::move if the compiler supports
+/// r-value references; otherwise, expands to the argument.
+#if LLVM_USE_RVALUE_REFERENCES
+#define llvm_move(value) (::std::move(value))
+#else
+#define llvm_move(value) (value)
+#endif
+
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// 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
@@ -102,7 +121,7 @@
// 3.4 supported this but is buggy in various cases and produces unimplemented
// errors, just use it in GCC 4.0 and later.
#if __GNUC__ > 3
-#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
#else
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index ced3a2cf2dbd..90dd69fa478f 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -155,6 +155,10 @@ public:
/// constant range.
ConstantRange subtract(const APInt &CI) const;
+ /// \brief Subtract the specified range from this range (aka relative
+ /// complement of the sets).
+ ConstantRange difference(const ConstantRange &CR) const;
+
/// intersectWith - Return the range that results from the intersection of
/// this range with another range. The resultant range is guaranteed to
/// include all elements contained in both input ranges, and to have the
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index a3a6489e8a52..7484abd36868 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -79,18 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#endif
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index b492bb14ba50..b9fb48a1d498 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -79,18 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#endif
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index e72327271f23..896fe849a6be 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -19,7 +19,7 @@
// foo class.
//
// When compiling without assertions, the -debug-* options and all code in
-// DEBUG() statements disappears, so it does not effect the runtime of the code.
+// DEBUG() statements disappears, so it does not affect the runtime of the code.
//
//===----------------------------------------------------------------------===//
@@ -49,11 +49,11 @@ extern bool DebugFlag;
///
bool isCurrentDebugType(const char *Type);
-/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X
+/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
/// option were specified. Note that DebugFlag also needs to be set to true for
/// debug output to be produced.
///
-void SetCurrentDebugType(const char *Type);
+void setCurrentDebugType(const char *Type);
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
/// information. In the '-debug' option is specified on the commandline, and if
@@ -70,7 +70,7 @@ void SetCurrentDebugType(const char *Type);
#else
#define isCurrentDebugType(X) (false)
-#define SetCurrentDebugType(X)
+#define setCurrentDebugType(X)
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
#endif
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 2ee9f876c366..049807570711 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -15,9 +15,8 @@
#ifndef LLVM_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H
-#include "llvm/ADT/DenseMapInfo.h"
-
namespace llvm {
+ template <typename T> struct DenseMapInfo;
class MDNode;
class LLVMContext;
@@ -103,10 +102,10 @@ namespace llvm {
template <>
struct DenseMapInfo<DebugLoc> {
- static DebugLoc getEmptyKey();
- static DebugLoc getTombstoneKey();
+ static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
+ static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
static unsigned getHashValue(const DebugLoc &Key);
- static bool isEqual(const DebugLoc &LHS, const DebugLoc &RHS);
+ static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
};
} // end namespace llvm
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 04953b6e5657..f7ae60fef74b 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -248,7 +248,7 @@ enum {
EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor
EM_R32C = 162, // Renesas R32C series microprocessors
EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family
- EM_QDSP6 = 164, // QUALCOMM DSP6 Processor
+ EM_HEXAGON = 164, // Qualcomm Hexagon processor
EM_8051 = 165, // Intel 8051 and variants
EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable
// and extensible RISC processors
@@ -674,6 +674,97 @@ enum {
R_MIPS_NUM = 218
};
+// ELF Relocation types for Hexagon
+// Release 5 ABI - Document: 80-V9418-3 Rev. J
+enum {
+ R_HEX_NONE = 0,
+ R_HEX_B22_PCREL = 1,
+ R_HEX_B15_PCREL = 2,
+ R_HEX_B7_PCREL = 3,
+ R_HEX_LO16 = 4,
+ R_HEX_HI16 = 5,
+ R_HEX_32 = 6,
+ R_HEX_16 = 7,
+ R_HEX_8 = 8,
+ R_HEX_GPREL16_0 = 9,
+ R_HEX_GPREL16_1 = 10,
+ R_HEX_GPREL16_2 = 11,
+ R_HEX_GPREL16_3 = 12,
+ R_HEX_HL16 = 13,
+ R_HEX_B13_PCREL = 14,
+ R_HEX_B9_PCREL = 15,
+ R_HEX_B32_PCREL_X = 16,
+ R_HEX_32_6_X = 17,
+ R_HEX_B22_PCREL_X = 18,
+ R_HEX_B15_PCREL_X = 19,
+ R_HEX_B13_PCREL_X = 20,
+ R_HEX_B9_PCREL_X = 21,
+ R_HEX_B7_PCREL_X = 22,
+ R_HEX_16_X = 23,
+ R_HEX_12_X = 24,
+ R_HEX_11_X = 25,
+ R_HEX_10_X = 26,
+ R_HEX_9_X = 27,
+ R_HEX_8_X = 28,
+ R_HEX_7_X = 29,
+ R_HEX_6_X = 30,
+ R_HEX_32_PCREL = 31,
+ R_HEX_COPY = 32,
+ R_HEX_GLOB_DAT = 33,
+ R_HEX_JMP_SLOT = 34,
+ R_HEX_RELATIVE = 35,
+ R_HEX_PLT_B22_PCREL = 36,
+ R_HEX_GOTREL_LO16 = 37,
+ R_HEX_GOTREL_HI16 = 38,
+ R_HEX_GOTREL_32 = 39,
+ R_HEX_GOT_LO16 = 40,
+ R_HEX_GOT_HI16 = 41,
+ R_HEX_GOT_32 = 42,
+ R_HEX_GOT_16 = 43,
+ R_HEX_DTPMOD_32 = 44,
+ R_HEX_DTPREL_LO16 = 45,
+ R_HEX_DTPREL_HI16 = 46,
+ R_HEX_DTPREL_32 = 47,
+ R_HEX_DTPREL_16 = 48,
+ R_HEX_GD_PLT_B22_PCREL = 49,
+ R_HEX_GD_GOT_LO16 = 50,
+ R_HEX_GD_GOT_HI16 = 51,
+ R_HEX_GD_GOT_32 = 52,
+ R_HEX_GD_GOT_16 = 53,
+ R_HEX_IE_LO16 = 54,
+ R_HEX_IE_HI16 = 55,
+ R_HEX_IE_32 = 56,
+ R_HEX_IE_GOT_LO16 = 57,
+ R_HEX_IE_GOT_HI16 = 58,
+ R_HEX_IE_GOT_32 = 59,
+ R_HEX_IE_GOT_16 = 60,
+ R_HEX_TPREL_LO16 = 61,
+ R_HEX_TPREL_HI16 = 62,
+ R_HEX_TPREL_32 = 63,
+ R_HEX_TPREL_16 = 64,
+ R_HEX_6_PCREL_X = 65,
+ R_HEX_GOTREL_32_6_X = 66,
+ R_HEX_GOTREL_16_X = 67,
+ R_HEX_GOTREL_11_X = 68,
+ R_HEX_GOT_32_6_X = 69,
+ R_HEX_GOT_16_X = 70,
+ R_HEX_GOT_11_X = 71,
+ R_HEX_DTPREL_32_6_X = 72,
+ R_HEX_DTPREL_16_X = 73,
+ R_HEX_DTPREL_11_X = 74,
+ R_HEX_GD_GOT_32_6_X = 75,
+ R_HEX_GD_GOT_16_X = 76,
+ R_HEX_GD_GOT_11_X = 77,
+ R_HEX_IE_32_6_X = 78,
+ R_HEX_IE_16_X = 79,
+ R_HEX_IE_GOT_32_6_X = 80,
+ R_HEX_IE_GOT_16_X = 81,
+ R_HEX_IE_GOT_11_X = 82,
+ R_HEX_TPREL_32_6_X = 83,
+ R_HEX_TPREL_16_X = 84,
+ R_HEX_TPREL_11_X = 85
+};
+
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)
@@ -736,6 +827,8 @@ enum {
SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_GNU_ATTRIBUTES= 0x6ffffff5, // Object attributes.
+ SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
@@ -1017,6 +1110,9 @@ enum {
PT_SUNW_EH_FRAME = 0x6474e550,
PT_SUNW_UNWIND = 0x6464e550,
+ PT_GNU_STACK = 0x6474e551, // Indicates stack executability.
+ PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
+
PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type.
PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
@@ -1095,7 +1191,16 @@ enum {
DT_LOOS = 0x60000000, // Start of environment specific tags.
DT_HIOS = 0x6FFFFFFF, // End of environment specific tags.
DT_LOPROC = 0x70000000, // Start of processor specific tags.
- DT_HIPROC = 0x7FFFFFFF // End of processor specific tags.
+ DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags.
+
+ DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count.
+ DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count.
+
+ DT_FLAGS_1 = 0X6FFFFFFB, // Flags_1.
+ DT_VERDEF = 0X6FFFFFFC, // The address of the version definition table.
+ DT_VERDEFNUM = 0X6FFFFFFD, // The number of entries in DT_VERDEF.
+ DT_VERNEED = 0X6FFFFFFE, // The address of the version Dependency table.
+ DT_VERNEEDNUM = 0X6FFFFFFF // The number of entries in DT_VERNEED.
};
// DT_FLAGS values.
@@ -1107,6 +1212,27 @@ enum {
DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically.
};
+// State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry.
+enum {
+ DF_1_NOW = 0x00000001, // Set RTLD_NOW for this object.
+ DF_1_GLOBAL = 0x00000002, // Set RTLD_GLOBAL for this object.
+ DF_1_GROUP = 0x00000004, // Set RTLD_GROUP for this object.
+ DF_1_NODELETE = 0x00000008, // Set RTLD_NODELETE for this object.
+ DF_1_LOADFLTR = 0x00000010, // Trigger filtee loading at runtime.
+ DF_1_INITFIRST = 0x00000020, // Set RTLD_INITFIRST for this object.
+ DF_1_NOOPEN = 0x00000040, // Set RTLD_NOOPEN for this object.
+ DF_1_ORIGIN = 0x00000080, // $ORIGIN must be handled.
+ DF_1_DIRECT = 0x00000100, // Direct binding enabled.
+ DF_1_TRANS = 0x00000200,
+ DF_1_INTERPOSE = 0x00000400, // Object is used to interpose.
+ DF_1_NODEFLIB = 0x00000800, // Ignore default lib search path.
+ DF_1_NODUMP = 0x00001000, // Object can't be dldump'ed.
+ DF_1_CONFALT = 0x00002000, // Configuration alternative created.
+ DF_1_ENDFILTEE = 0x00004000, // Filtee terminates filters search.
+ DF_1_DISPRELDNE = 0x00008000, // Disp reloc applied at build time.
+ DF_1_DISPRELPND = 0x00010000 // Disp reloc applied at run-time.
+};
+
// ElfXX_VerDef structure version (GNU versioning)
enum {
VER_DEF_NONE = 0,
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 733ab7548fca..8d5649dc1f91 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -49,7 +49,7 @@ struct alignment_access_helper<value_type, unaligned>
namespace endian {
template<typename value_type, alignment align>
- static value_type read_le(const void *memory) {
+ inline value_type read_le(const void *memory) {
value_type t =
reinterpret_cast<const detail::alignment_access_helper
<value_type, align> *>(memory)->val;
@@ -59,7 +59,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static void write_le(void *memory, value_type value) {
+ 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> *>
@@ -67,7 +67,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static value_type read_be(const void *memory) {
+ inline value_type read_be(const void *memory) {
value_type t =
reinterpret_cast<const detail::alignment_access_helper
<value_type, align> *>(memory)->val;
@@ -77,7 +77,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static void write_be(void *memory, value_type value) {
+ inline void write_be(void *memory, value_type value) {
if (sys::isLittleEndianHost())
value = sys::SwapByteOrder(value);
reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
new file mode 100644
index 000000000000..0f07164eb8ed
--- /dev/null
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -0,0 +1,97 @@
+//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility for creating a in-memory buffer that will be written to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class error_code;
+template<class T> class OwningPtr;
+
+/// FileOutputBuffer - This interface provides simple way to create an in-memory
+/// buffer which will be written to a file. During the lifetime of these
+/// objects, the content or existence of the specified file is undefined. That
+/// is, creating an OutputBuffer for a file may immediately remove the file.
+/// If the FileOutputBuffer is committed, the target file's content will become
+/// the buffer content at the time of the commit. If the FileOutputBuffer is
+/// not committed, the file will be deleted in the FileOutputBuffer destructor.
+class FileOutputBuffer {
+public:
+
+ enum {
+ F_executable = 1 /// set the 'x' bit on the resulting file
+ };
+
+ /// Factory method to create an OutputBuffer object which manages a read/write
+ /// buffer of the specified size. When committed, the buffer will be written
+ /// to the file at the specified path.
+ static error_code create(StringRef FilePath, size_t Size,
+ OwningPtr<FileOutputBuffer> &Result,
+ unsigned Flags=0);
+
+
+ /// Returns a pointer to the start of the buffer.
+ uint8_t *getBufferStart() const {
+ return BufferStart;
+ }
+
+ /// Returns a pointer to the end of the buffer.
+ uint8_t *getBufferEnd() const {
+ return BufferEnd;
+ }
+
+ /// Returns size of the buffer.
+ size_t getBufferSize() const {
+ return BufferEnd - BufferStart;
+ }
+
+ /// Returns path where file will show up if buffer is committed.
+ StringRef getPath() const {
+ return FinalPath;
+ }
+
+ /// Flushes the content of the buffer to its file and deallocates the
+ /// buffer. If commit() is not called before this object's destructor
+ /// is called, the file is deleted in the destructor. The optional parameter
+ /// is used if it turns out you want the file size to be smaller than
+ /// initially requested.
+ error_code commit(int64_t NewSmallerSize = -1);
+
+ /// If this object was previously committed, the destructor just deletes
+ /// this object. If this object was not committed, the destructor
+ /// deallocates the buffer and the target file is never written.
+ ~FileOutputBuffer();
+
+
+protected:
+ FileOutputBuffer(const FileOutputBuffer &); // DO NOT IMPLEMENT
+ FileOutputBuffer &operator=(const FileOutputBuffer &); // DO NOT IMPLEMENT
+ FileOutputBuffer(uint8_t *Start, uint8_t *End,
+ StringRef Path, StringRef TempPath);
+
+ uint8_t *BufferStart;
+ uint8_t *BufferEnd;
+ SmallString<128> FinalPath;
+ SmallString<128> TempPath;
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index e6f9926af6f8..e0353f957a7c 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -94,13 +94,62 @@ struct space_info {
uint64_t available;
};
+
+enum perms {
+ no_perms = 0,
+ owner_read = 0400,
+ owner_write = 0200,
+ owner_exe = 0100,
+ owner_all = owner_read | owner_write | owner_exe,
+ group_read = 040,
+ group_write = 020,
+ group_exe = 010,
+ group_all = group_read | group_write | group_exe,
+ others_read = 04,
+ others_write = 02,
+ others_exe = 01,
+ others_all = others_read | others_write | others_exe,
+ all_all = owner_all | group_all | others_all,
+ set_uid_on_exe = 04000,
+ set_gid_on_exe = 02000,
+ sticky_bit = 01000,
+ perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
+ perms_not_known = 0xFFFF,
+ add_perms = 0x1000,
+ remove_perms = 0x2000,
+ symlink_perms = 0x4000
+};
+
+// Helper functions so that you can use & and | to manipulate perms bits:
+inline perms operator|(perms l , perms r) {
+ return static_cast<perms>(
+ static_cast<unsigned short>(l) | static_cast<unsigned short>(r));
+}
+inline perms operator&(perms l , perms r) {
+ return static_cast<perms>(
+ static_cast<unsigned short>(l) & static_cast<unsigned short>(r));
+}
+inline perms &operator|=(perms &l, perms r) {
+ l = l | r;
+ return l;
+}
+inline perms &operator&=(perms &l, perms r) {
+ l = l & r;
+ return l;
+}
+inline perms operator~(perms x) {
+ return static_cast<perms>(~static_cast<unsigned short>(x));
+}
+
+
+
/// file_status - Represents the result of a call to stat and friends. It has
/// a platform specific member to store the result.
class file_status
{
#if defined(LLVM_ON_UNIX)
- dev_t st_dev;
- ino_t st_ino;
+ dev_t fs_st_dev;
+ ino_t fs_st_ino;
#elif defined (LLVM_ON_WIN32)
uint32_t LastWriteTimeHigh;
uint32_t LastWriteTimeLow;
@@ -113,12 +162,19 @@ class file_status
friend bool equivalent(file_status A, file_status B);
friend error_code status(const Twine &path, file_status &result);
file_type Type;
+ perms Perms;
public:
- explicit file_status(file_type v=file_type::status_error)
- : Type(v) {}
+ explicit file_status(file_type v=file_type::status_error,
+ perms prms=perms_not_known)
+ : Type(v), Perms(prms) {}
+ // getters
file_type type() const { return Type; }
+ perms permissions() const { return Perms; }
+
+ // setters
void type(file_type v) { Type = v; }
+ void permissions(perms p) { Perms = p; }
};
/// file_magic - An "enum class" enumeration of file types based on magic (the first
@@ -309,6 +365,13 @@ bool equivalent(file_status A, file_status B);
/// platform specific error_code.
error_code equivalent(const Twine &A, const Twine &B, bool &result);
+/// @brief Simpler version of equivalent for clients that don't need to
+/// differentiate between an error and false.
+inline bool equivalent(const Twine &A, const Twine &B) {
+ bool result;
+ return !equivalent(A, B, result) && result;
+}
+
/// @brief Get file size.
///
/// @param path Input path.
@@ -388,6 +451,13 @@ error_code is_symlink(const Twine &path, bool &result);
/// platform specific error_code.
error_code status(const Twine &path, file_status &result);
+/// @brief Modifies permission bits on a file
+///
+/// @param path Input path.
+/// @results errc::success if permissions have been changed, otherwise a
+/// platform specific error_code.
+error_code permissions(const Twine &path, perms prms);
+
/// @brief Is status available?
///
/// @param path Input path.
@@ -422,8 +492,8 @@ error_code status_known(const Twine &path, bool &result);
/// @results errc::success if result_{fd,path} have been successfully set,
/// otherwise a platform specific error_code.
error_code unique_file(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path,
- bool makeAbsolute = true);
+ SmallVectorImpl<char> &result_path,
+ bool makeAbsolute = true, unsigned mode = 0600);
/// @brief Canonicalize path.
///
@@ -506,6 +576,33 @@ error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
error_code GetMainExecutable(const char *argv0, void *MainAddr,
SmallVectorImpl<char> &result);
+
+/// @brief Memory maps the contents of a file
+///
+/// @param path Path to file to map.
+/// @param file_offset Byte offset in file where mapping should begin.
+/// @param size_t Byte length of range of the file to map.
+/// @param map_writable If true, the file will be mapped in r/w such
+/// that changes to the mapped buffer will be flushed back
+/// to the file. If false, the file will be mapped read-only
+/// and the buffer will be read-only.
+/// @param result Set to the start address of the mapped buffer.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
+ bool map_writable, void *&result);
+
+
+/// @brief Memory unmaps the contents of a file
+///
+/// @param base Pointer to the start of the buffer.
+/// @param size Byte length of the range to unmmap.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code unmap_file_pages(void *base, size_t size);
+
+
+
/// @}
/// @name Iterators
/// @{
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index 49cd87fc7b44..19e1ce89cbd5 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -63,8 +63,8 @@ public:
bool readFunctionTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\0' || Tag[3] != '\1') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\1') {
return false;
}
Cursor += 4;
@@ -76,8 +76,8 @@ public:
bool readBlockTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x41' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x41' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -89,8 +89,8 @@ public:
bool readEdgeTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x43' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x43' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -102,8 +102,8 @@ public:
bool readLineTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x45' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x45' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -115,8 +115,8 @@ public:
bool readArcTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\xa1' || Tag[3] != '\1') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\xa1' || Tag[3] != '\1') {
return false;
}
Cursor += 4;
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index ae32da59dc22..f178b0caa8aa 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -172,7 +172,7 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
- O << "|" << (void*)Node;
+ O << "|" << static_cast<const void*>(Node);
}
std::string edgeSourceLabels;
@@ -192,7 +192,7 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
- O << "|" << (void*)Node;
+ O << "|" << static_cast<const void*>(Node);
}
if (DTraits.hasEdgeDestLabels()) {
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 52de8f660dd1..109b3cff85b6 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -13,6 +13,8 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
@@ -145,14 +147,17 @@ public:
// visitMul to proxy to visitBinaryOperator for instance in case the user does
// not need this generality.
//
- // The one problem case we have to handle here though is that the PHINode
- // class and opcode name are the exact same. Because of this, we cannot
- // define visitPHINode (the inst version) to forward to visitPHINode (the
- // generic version) without multiply defined symbols and recursion. To handle
- // this, we do not autoexpand "Other" instructions, we do it manually.
- //
+ // These functions can also implement fan-out, when a single opcode and
+ // instruction have multiple more specific Instruction subclasses. The Call
+ // instruction currently supports this. We implement that by redirecting that
+ // instruction to a special delegation helper.
#define HANDLE_INST(NUM, OPCODE, CLASS) \
- RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+ RetTy visit##OPCODE(CLASS &I) { \
+ if (NUM == Instruction::Call) \
+ return delegateCallInst(I); \
+ else \
+ DELEGATE(CLASS); \
+ }
#include "llvm/Instruction.def"
// Specific Instruction type classes... note that all of the casts are
@@ -195,6 +200,17 @@ public:
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+ // Handle the special instrinsic instruction classes.
+ RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
+
// Call and Invoke are slightly different as they delegate first through
// a generic CallSite visitor.
RetTy visitCallInst(CallInst &I) {
@@ -234,6 +250,29 @@ public:
// Note that you MUST override this function if your return type is not void.
//
void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+
+private:
+ // Special helper function to delegate to CallInst subclass visitors.
+ RetTy delegateCallInst(CallInst &I) {
+ if (const Function *F = I.getCalledFunction()) {
+ switch ((Intrinsic::ID)F->getIntrinsicID()) {
+ default: DELEGATE(IntrinsicInst);
+ case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
+ case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
+ case Intrinsic::memcpy: DELEGATE(MemCpyInst);
+ case Intrinsic::memmove: DELEGATE(MemMoveInst);
+ case Intrinsic::memset: DELEGATE(MemSetInst);
+ case Intrinsic::not_intrinsic: break;
+ }
+ }
+ DELEGATE(CallInst);
+ }
+
+ // An overload that will never actually be called, it is used only from dead
+ // code in the dispatching from opcodes to instruction subclasses.
+ RetTy delegateCallInst(Instruction &I) {
+ llvm_unreachable("delegateCallInst called for non-CallInst");
+ }
};
#undef DELEGATE
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
new file mode 100644
index 000000000000..bb9e76925ed5
--- /dev/null
+++ b/include/llvm/Support/IntegersSubset.h
@@ -0,0 +1,541 @@
+//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains class that implements constant set of ranges:
+/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
+/// SwitchInst and was used for case value representation that may contain
+/// multiple ranges for a single successor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CONSTANTRANGESSET_H_
+#define CONSTANTRANGESSET_H_
+
+#include <list>
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
+
+namespace llvm {
+
+ // The IntItem is a wrapper for APInt.
+ // 1. It determines sign of integer, it allows to use
+ // comparison operators >,<,>=,<=, and as result we got shorter and cleaner
+ // constructions.
+ // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
+ // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
+ // It allows to provide SwitchInst methods that works with ConstantInt for
+ // non-updated passes. And it allows to use APInt interface for new methods.
+ // 4. IntItem can be easily replaced with APInt.
+
+ // The set of macros that allows to propagate APInt operators to the IntItem.
+
+#define INT_ITEM_DEFINE_COMPARISON(op,func) \
+ bool operator op (const APInt& RHS) const { \
+ return getAPIntValue().func(RHS); \
+ }
+
+#define INT_ITEM_DEFINE_UNARY_OP(op) \
+ IntItem operator op () const { \
+ APInt res = op(getAPIntValue()); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ return IntItem(cast<ConstantInt>(NewVal)); \
+ }
+
+#define INT_ITEM_DEFINE_BINARY_OP(op) \
+ IntItem operator op (const APInt& RHS) const { \
+ APInt res = getAPIntValue() op RHS; \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ return IntItem(cast<ConstantInt>(NewVal)); \
+ }
+
+#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
+ IntItem& operator op (const APInt& RHS) {\
+ APInt res = getAPIntValue();\
+ res op RHS; \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return *this; \
+ }
+
+#define INT_ITEM_DEFINE_PREINCDEC(op) \
+ IntItem& operator op () { \
+ APInt res = getAPIntValue(); \
+ op(res); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return *this; \
+ }
+
+#define INT_ITEM_DEFINE_POSTINCDEC(op) \
+ IntItem& operator op (int) { \
+ APInt res = getAPIntValue();\
+ op(res); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ OldConstantIntVal = ConstantIntVal; \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return IntItem(OldConstantIntVal); \
+ }
+
+#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
+ RetTy operator op (IntTy RHS) const { \
+ return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
+ }
+
+class IntItem {
+ ConstantInt *ConstantIntVal;
+ const APInt* APIntVal;
+ IntItem(const ConstantInt *V) :
+ ConstantIntVal(const_cast<ConstantInt*>(V)),
+ APIntVal(&ConstantIntVal->getValue()){}
+ const APInt& getAPIntValue() const {
+ return *APIntVal;
+ }
+public:
+
+ IntItem() {}
+
+ operator const APInt&() const {
+ return getAPIntValue();
+ }
+
+ // Propagate APInt operators.
+ // Note, that
+ // /,/=,>>,>>= are not implemented in APInt.
+ // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
+
+ INT_ITEM_DEFINE_COMPARISON(<, ult)
+ INT_ITEM_DEFINE_COMPARISON(>, ugt)
+ INT_ITEM_DEFINE_COMPARISON(<=, ule)
+ INT_ITEM_DEFINE_COMPARISON(>=, uge)
+
+ INT_ITEM_DEFINE_COMPARISON(==, eq)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
+
+ INT_ITEM_DEFINE_COMPARISON(!=, ne)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
+
+ INT_ITEM_DEFINE_BINARY_OP(*)
+ INT_ITEM_DEFINE_BINARY_OP(+)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
+ INT_ITEM_DEFINE_BINARY_OP(-)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
+ INT_ITEM_DEFINE_BINARY_OP(<<)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
+ INT_ITEM_DEFINE_BINARY_OP(&)
+ INT_ITEM_DEFINE_BINARY_OP(^)
+ INT_ITEM_DEFINE_BINARY_OP(|)
+
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
+
+ // Special case for <<=
+ IntItem& operator <<= (unsigned RHS) {
+ APInt res = getAPIntValue();
+ res <<= RHS;
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
+ ConstantIntVal = cast<ConstantInt>(NewVal);
+ return *this;
+ }
+
+ INT_ITEM_DEFINE_UNARY_OP(-)
+ INT_ITEM_DEFINE_UNARY_OP(~)
+
+ INT_ITEM_DEFINE_PREINCDEC(++)
+ INT_ITEM_DEFINE_PREINCDEC(--)
+
+ // The set of workarounds, since currently we use ConstantInt implemented
+ // integer.
+
+ static IntItem fromConstantInt(const ConstantInt *V) {
+ return IntItem(V);
+ }
+ static IntItem fromType(Type* Ty, const APInt& V) {
+ ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
+ return fromConstantInt(C);
+ }
+ static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
+ ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
+ LikeThis.ConstantIntVal->getContext(), V));
+ return fromConstantInt(C);
+ }
+ ConstantInt *toConstantInt() const {
+ return ConstantIntVal;
+ }
+};
+
+template<class IntType>
+class IntRange {
+protected:
+ IntType Low;
+ IntType High;
+ bool IsEmpty : 1;
+ bool IsSingleNumber : 1;
+
+public:
+ typedef IntRange<IntType> self;
+ typedef std::pair<self, self> SubRes;
+
+ IntRange() : IsEmpty(true) {}
+ IntRange(const self &RHS) :
+ Low(RHS.Low), High(RHS.High),
+ IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
+ IntRange(const IntType &C) :
+ Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
+
+ IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
+ IsEmpty(false), IsSingleNumber(Low == High) {}
+
+ bool isEmpty() const { return IsEmpty; }
+ bool isSingleNumber() const { return IsSingleNumber; }
+
+ const IntType& getLow() const {
+ assert(!IsEmpty && "Range is empty.");
+ return Low;
+ }
+ const IntType& getHigh() const {
+ assert(!IsEmpty && "Range is empty.");
+ return High;
+ }
+
+ bool operator<(const self &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ if (Low == RHS.Low) {
+ if (High > RHS.High)
+ return true;
+ return false;
+ }
+ if (Low < RHS.Low)
+ return true;
+ return false;
+ }
+
+ bool operator==(const self &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ return Low == RHS.Low && High == RHS.High;
+ }
+
+ bool operator!=(const self &RHS) const {
+ return !operator ==(RHS);
+ }
+
+ static bool LessBySize(const self &LHS, const self &RHS) {
+ return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
+ }
+
+ bool isInRange(const IntType &IntVal) const {
+ assert(!IsEmpty && "Range is empty.");
+ return IntVal >= Low && IntVal <= High;
+ }
+
+ SubRes sub(const self &RHS) const {
+ SubRes Res;
+
+ // RHS is either more global and includes this range or
+ // if it doesn't intersected with this range.
+ if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
+
+ // If RHS more global (it is enough to check
+ // only one border in this case.
+ if (RHS.isInRange(Low))
+ return std::make_pair(self(Low, High), self());
+
+ return Res;
+ }
+
+ if (Low < RHS.Low) {
+ Res.first.Low = Low;
+ IntType NewHigh = RHS.Low;
+ --NewHigh;
+ Res.first.High = NewHigh;
+ }
+ if (High > RHS.High) {
+ IntType NewLow = RHS.High;
+ ++NewLow;
+ Res.second.Low = NewLow;
+ Res.second.High = High;
+ }
+ return Res;
+ }
+ };
+
+//===----------------------------------------------------------------------===//
+/// IntegersSubsetGeneric - class that implements the subset of integers. It
+/// consists from ranges and single numbers.
+template <class IntTy>
+class IntegersSubsetGeneric {
+public:
+ // Use Chris Lattner idea, that was initially described here:
+ // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
+ // In short, for more compact memory consumption we can store flat
+ // numbers collection, and define range as pair of indices.
+ // In that case we can safe some memory on 32 bit machines.
+ typedef std::vector<IntTy> FlatCollectionTy;
+ typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
+ typedef std::vector<RangeLinkTy> RangeLinksTy;
+ typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
+
+ typedef IntegersSubsetGeneric<IntTy> self;
+
+protected:
+
+ FlatCollectionTy FlatCollection;
+ RangeLinksTy RangeLinks;
+
+ bool IsSingleNumber;
+ bool IsSingleNumbersOnly;
+
+public:
+
+ template<class RangesCollectionTy>
+ explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
+ assert(Links.size() && "Empty ranges are not allowed.");
+
+ // In case of big set of single numbers consumes additional RAM space,
+ // but allows to avoid additional reallocation.
+ FlatCollection.reserve(Links.size() * 2);
+ RangeLinks.reserve(Links.size());
+ IsSingleNumbersOnly = true;
+ for (typename RangesCollectionTy::const_iterator i = Links.begin(),
+ e = Links.end(); i != e; ++i) {
+ RangeLinkTy RangeLink;
+ FlatCollection.push_back(i->getLow());
+ RangeLink.first = &FlatCollection.back();
+ if (i->getLow() != i->getHigh()) {
+ FlatCollection.push_back(i->getHigh());
+ IsSingleNumbersOnly = false;
+ }
+ RangeLink.second = &FlatCollection.back();
+ RangeLinks.push_back(RangeLink);
+ }
+ IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
+ }
+
+ IntegersSubsetGeneric(const self& RHS) {
+ *this = RHS;
+ }
+
+ self& operator=(const self& RHS) {
+ FlatCollection.clear();
+ RangeLinks.clear();
+ FlatCollection.reserve(RHS.RangeLinks.size() * 2);
+ RangeLinks.reserve(RHS.RangeLinks.size());
+ for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
+ i != e; ++i) {
+ RangeLinkTy RangeLink;
+ FlatCollection.push_back(*(i->first));
+ RangeLink.first = &FlatCollection.back();
+ if (i->first != i->second)
+ FlatCollection.push_back(*(i->second));
+ RangeLink.second = &FlatCollection.back();
+ RangeLinks.push_back(RangeLink);
+ }
+ IsSingleNumber = RHS.IsSingleNumber;
+ IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
+ return *this;
+ }
+
+ typedef IntRange<IntTy> Range;
+
+ /// Checks is the given constant satisfies this case. Returns
+ /// true if it equals to one of contained values or belongs to the one of
+ /// contained ranges.
+ bool isSatisfies(const IntTy &CheckingVal) const {
+ if (IsSingleNumber)
+ return FlatCollection.front() == CheckingVal;
+ if (IsSingleNumbersOnly)
+ return std::find(FlatCollection.begin(),
+ FlatCollection.end(),
+ CheckingVal) != FlatCollection.end();
+
+ for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
+ if (RangeLinks[i].first == RangeLinks[i].second) {
+ if (*RangeLinks[i].first == CheckingVal)
+ return true;
+ } else if (*RangeLinks[i].first <= CheckingVal &&
+ *RangeLinks[i].second >= CheckingVal)
+ return true;
+ }
+ return false;
+ }
+
+ /// Returns set's item with given index.
+ Range getItem(unsigned idx) const {
+ const RangeLinkTy &Link = RangeLinks[idx];
+ if (Link.first != Link.second)
+ return Range(*Link.first, *Link.second);
+ else
+ return Range(*Link.first);
+ }
+
+ /// Return number of items (ranges) stored in set.
+ unsigned getNumItems() const {
+ return RangeLinks.size();
+ }
+
+ /// Returns true if whole subset contains single element.
+ bool isSingleNumber() const {
+ return IsSingleNumber;
+ }
+
+ /// Returns true if whole subset contains only single numbers, no ranges.
+ bool isSingleNumbersOnly() const {
+ return IsSingleNumbersOnly;
+ }
+
+ /// Does the same like getItem(idx).isSingleNumber(), but
+ /// works faster, since we avoid creation of temporary range object.
+ bool isSingleNumber(unsigned idx) const {
+ return RangeLinks[idx].first == RangeLinks[idx].second;
+ }
+
+ /// Returns set the size, that equals number of all values + sizes of all
+ /// ranges.
+ /// Ranges set is considered as flat numbers collection.
+ /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
+ /// for range [<0>, <1>, <5>] the size will 3
+ unsigned getSize() const {
+ APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
+ for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
+ const APInt &Low = getItem(i).getLow();
+ const APInt &High = getItem(i).getHigh();
+ APInt S = High - Low + 1;
+ sz += S;
+ }
+ return sz.getZExtValue();
+ }
+
+ /// Allows to access single value even if it belongs to some range.
+ /// Ranges set is considered as flat numbers collection.
+ /// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
+ /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
+ APInt getSingleValue(unsigned idx) const {
+ APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
+ for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
+ const APInt &Low = getItem(i).getLow();
+ const APInt &High = getItem(i).getHigh();
+ APInt S = High - Low + 1;
+ APInt oldSz = sz;
+ sz += S;
+ if (sz.ugt(idx)) {
+ APInt Res = Low;
+ APInt Offset(oldSz.getBitWidth(), idx);
+ Offset -= oldSz;
+ Res += Offset;
+ return Res;
+ }
+ }
+ assert(0 && "Index exceeds high border.");
+ return sz;
+ }
+
+ /// Does the same as getSingleValue, but works only if subset contains
+ /// single numbers only.
+ const IntTy& getSingleNumber(unsigned idx) const {
+ assert(IsSingleNumbersOnly && "This method works properly if subset "
+ "contains single numbers only.");
+ return FlatCollection[idx];
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// IntegersSubset - currently is extension of IntegersSubsetGeneric
+/// that also supports conversion to/from Constant* object.
+class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
+
+ typedef IntegersSubsetGeneric<IntItem> ParentTy;
+
+ Constant *Holder;
+
+ static unsigned getNumItemsFromConstant(Constant *C) {
+ return cast<ArrayType>(C->getType())->getNumElements();
+ }
+
+ static Range getItemFromConstant(Constant *C, unsigned idx) {
+ const Constant *CV = C->getAggregateElement(idx);
+
+ unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
+ switch (NumEls) {
+ case 1:
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(cast<ConstantInt>(
+ cast<ConstantInt>(CV->getAggregateElement(0U)))));
+ case 2:
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(1))));
+ default:
+ assert(0 && "Only pairs and single numbers are allowed here.");
+ return Range();
+ }
+ }
+
+ std::vector<Range> rangesFromConstant(Constant *C) {
+ unsigned NumItems = getNumItemsFromConstant(C);
+ std::vector<Range> r;
+ r.reserve(NumItems);
+ for (unsigned i = 0, e = NumItems; i != e; ++i)
+ r.push_back(getItemFromConstant(C, i));
+ return r;
+ }
+
+public:
+
+ explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
+ Holder(C) {}
+
+ IntegersSubset(const IntegersSubset& RHS) :
+ ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
+ Holder(RHS.Holder) {}
+
+ template<class RangesCollectionTy>
+ explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
+ std::vector<Constant*> Elts;
+ Elts.reserve(Src.size());
+ for (typename RangesCollectionTy::const_iterator i = Src.begin(),
+ e = Src.end(); i != e; ++i) {
+ const Range &R = *i;
+ std::vector<Constant*> r;
+ if (R.isSingleNumber()) {
+ r.reserve(2);
+ // FIXME: Since currently we have ConstantInt based numbers
+ // use hack-conversion of IntItem to ConstantInt
+ r.push_back(R.getLow().toConstantInt());
+ r.push_back(R.getHigh().toConstantInt());
+ } else {
+ r.reserve(1);
+ r.push_back(R.getLow().toConstantInt());
+ }
+ Constant *CV = ConstantVector::get(r);
+ Elts.push_back(CV);
+ }
+ ArrayType *ArrTy =
+ ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
+ Holder = ConstantArray::get(ArrTy, Elts);
+ }
+
+ operator Constant*() { return Holder; }
+ operator const Constant*() const { return Holder; }
+ Constant *operator->() { return Holder; }
+ const Constant *operator->() const { return Holder; }
+};
+
+}
+
+#endif /* CONSTANTRANGESSET_H_ */
diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
new file mode 100644
index 000000000000..cab18dce159b
--- /dev/null
+++ b/include/llvm/Support/IntegersSubsetMapping.h
@@ -0,0 +1,580 @@
+//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// IntegersSubsetMapping is mapping from A to B, where
+/// Items in A is subsets of integers,
+/// Items in B some pointers (Successors).
+/// If user which to add another subset for successor that is already
+/// exists in mapping, IntegersSubsetMapping merges existing subset with
+/// added one.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CRSBUILDER_H_
+#define CRSBUILDER_H_
+
+#include "llvm/Support/IntegersSubset.h"
+#include <list>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+template <class SuccessorClass,
+ class IntegersSubsetTy = IntegersSubset,
+ class IntTy = IntItem>
+class IntegersSubsetMapping {
+ // FIXME: To much similar iterators typedefs, similar names.
+ // - Rename RangeIterator to the cluster iterator.
+ // - Remove unused "add" methods.
+ // - Class contents needs cleaning.
+public:
+
+ typedef IntRange<IntTy> RangeTy;
+
+ struct RangeEx : public RangeTy {
+ RangeEx() : Weight(1) {}
+ RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
+ RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
+ RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
+ RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
+ RangeTy(L, H), Weight(W) {}
+ unsigned Weight;
+ };
+
+ typedef std::pair<RangeEx, SuccessorClass*> Cluster;
+
+ typedef std::list<RangeTy> RangesCollection;
+ typedef typename RangesCollection::iterator RangesCollectionIt;
+ typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
+ typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
+
+protected:
+
+ typedef std::list<Cluster> CaseItems;
+ typedef typename CaseItems::iterator CaseItemIt;
+ typedef typename CaseItems::const_iterator CaseItemConstIt;
+
+ // TODO: Change unclean CRS prefixes to SubsetMap for example.
+ typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
+ typedef typename CRSMap::iterator CRSMapIt;
+
+ struct ClustersCmp {
+ bool operator()(const Cluster &C1, const Cluster &C2) {
+ return C1.first < C2.first;
+ }
+ };
+
+ CaseItems Items;
+ bool Sorted;
+
+ bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
+ return LItem->first.getHigh() >= RItem->first.getLow();
+ }
+
+ bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
+ if (LItem->second != RItem->second) {
+ assert(!isIntersected(LItem, RItem) &&
+ "Intersected items with different successors!");
+ return false;
+ }
+ APInt RLow = RItem->first.getLow();
+ if (RLow != APInt::getNullValue(RLow.getBitWidth()))
+ --RLow;
+ return LItem->first.getHigh() >= RLow;
+ }
+
+ void sort() {
+ if (!Sorted) {
+ std::vector<Cluster> clustersVector;
+ clustersVector.reserve(Items.size());
+ clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
+ std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
+ Items.clear();
+ Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
+ Sorted = true;
+ }
+ }
+
+ enum DiffProcessState {
+ L_OPENED,
+ INTERSECT_OPENED,
+ R_OPENED,
+ ALL_IS_CLOSED
+ };
+
+ class DiffStateMachine {
+
+ DiffProcessState State;
+ IntTy OpenPt;
+ SuccessorClass *CurrentLSuccessor;
+ SuccessorClass *CurrentRSuccessor;
+
+ self *LeftMapping;
+ self *IntersectionMapping;
+ self *RightMapping;
+
+ public:
+
+ typedef
+ IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
+
+ DiffStateMachine(MappingTy *L,
+ MappingTy *Intersection,
+ MappingTy *R) :
+ State(ALL_IS_CLOSED),
+ LeftMapping(L),
+ IntersectionMapping(Intersection),
+ RightMapping(R)
+ {}
+
+ void onLOpen(const IntTy &Pt, SuccessorClass *S) {
+ switch (State) {
+ case R_OPENED:
+ if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
+ RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
+ State = INTERSECT_OPENED;
+ break;
+ case ALL_IS_CLOSED:
+ State = L_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentLSuccessor = S;
+ OpenPt = Pt;
+ }
+
+ void onLClose(const IntTy &Pt) {
+ switch (State) {
+ case L_OPENED:
+ assert(Pt >= OpenPt &&
+ "Subset is not sorted or contains overlapped ranges");
+ if (LeftMapping)
+ LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ OpenPt = Pt + 1;
+ State = R_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ void onROpen(const IntTy &Pt, SuccessorClass *S) {
+ switch (State) {
+ case L_OPENED:
+ if (Pt > OpenPt && LeftMapping)
+ LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
+ State = INTERSECT_OPENED;
+ break;
+ case ALL_IS_CLOSED:
+ State = R_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentRSuccessor = S;
+ OpenPt = Pt;
+ }
+
+ void onRClose(const IntTy &Pt) {
+ switch (State) {
+ case R_OPENED:
+ assert(Pt >= OpenPt &&
+ "Subset is not sorted or contains overlapped ranges");
+ if (RightMapping)
+ RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ OpenPt = Pt + 1;
+ State = L_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ void onLROpen(const IntTy &Pt,
+ SuccessorClass *LS,
+ SuccessorClass *RS) {
+ switch (State) {
+ case ALL_IS_CLOSED:
+ State = INTERSECT_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentLSuccessor = LS;
+ CurrentRSuccessor = RS;
+ OpenPt = Pt;
+ }
+
+ void onLRClose(const IntTy &Pt) {
+ switch (State) {
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ bool isLOpened() { return State == L_OPENED; }
+ bool isROpened() { return State == R_OPENED; }
+ };
+
+public:
+
+ // Don't public CaseItems itself. Don't allow edit the Items directly.
+ // Just present the user way to iterate over the internal collection
+ // sharing iterator, begin() and end(). Editing should be controlled by
+ // factory.
+ typedef CaseItemIt RangeIterator;
+
+ typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
+ typedef std::list<Case> Cases;
+ typedef typename Cases::iterator CasesIt;
+
+ IntegersSubsetMapping() {
+ Sorted = false;
+ }
+
+ bool verify() {
+ RangeIterator DummyErrItem;
+ return verify(DummyErrItem);
+ }
+
+ bool verify(RangeIterator& errItem) {
+ if (Items.empty())
+ return true;
+ sort();
+ for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
+ j != e; i = j++) {
+ if (isIntersected(i, j) && i->second != j->second) {
+ errItem = j;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool isOverlapped(self &RHS) {
+ if (Items.empty() || RHS.empty())
+ return true;
+
+ for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
+ el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
+
+ const RangeTy &LRange = L->first;
+ const RangeTy &RRange = R->first;
+
+ if (LRange.getLow() > RRange.getLow()) {
+ if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
+ ++R;
+ else
+ return true;
+ } else if (LRange.getLow() < RRange.getLow()) {
+ if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
+ ++L;
+ else
+ return true;
+ } else // iRange.getLow() == jRange.getLow()
+ return true;
+ }
+ return false;
+ }
+
+
+ void optimize() {
+ if (Items.size() < 2)
+ return;
+ sort();
+ CaseItems OldItems = Items;
+ Items.clear();
+ const IntTy *Low = &OldItems.begin()->first.getLow();
+ const IntTy *High = &OldItems.begin()->first.getHigh();
+ unsigned Weight = 1;
+ SuccessorClass *Successor = OldItems.begin()->second;
+ for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
+ j != e; i = j++) {
+ if (isJoinable(i, j)) {
+ const IntTy *CurHigh = &j->first.getHigh();
+ ++Weight;
+ if (*CurHigh > *High)
+ High = CurHigh;
+ } else {
+ RangeEx R(*Low, *High, Weight);
+ add(R, Successor);
+ Low = &j->first.getLow();
+ High = &j->first.getHigh();
+ Weight = 1;
+ Successor = j->second;
+ }
+ }
+ RangeEx R(*Low, *High, Weight);
+ add(R, Successor);
+ // We recollected the Items, but we kept it sorted.
+ Sorted = true;
+ }
+
+ /// Adds a constant value.
+ void add(const IntTy &C, SuccessorClass *S = 0) {
+ RangeTy R(C);
+ add(R, S);
+ }
+
+ /// Adds a range.
+ void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
+ RangeTy R(Low, High);
+ add(R, S);
+ }
+ void add(const RangeTy &R, SuccessorClass *S = 0) {
+ RangeEx REx = R;
+ add(REx, S);
+ }
+ void add(const RangeEx &R, SuccessorClass *S = 0) {
+ Items.push_back(std::make_pair(R, S));
+ Sorted = false;
+ }
+
+ /// Adds all ranges and values from given ranges set to the current
+ /// mapping.
+ void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0) {
+ for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
+ RangeTy R = CRS.getItem(i);
+ add(R, S);
+ }
+ }
+
+ void add(self& RHS) {
+ Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
+ }
+
+ void add(self& RHS, SuccessorClass *S) {
+ for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
+ add(i->first, S);
+ }
+
+ void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
+ for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
+ add(*i, S);
+ }
+
+ /// Removes items from set.
+ void removeItem(RangeIterator i) { Items.erase(i); }
+
+ /// Moves whole case from current mapping to the NewMapping object.
+ void detachCase(self& NewMapping, SuccessorClass *Succ) {
+ for (CaseItemIt i = Items.begin(); i != Items.end();)
+ if (i->second == Succ) {
+ NewMapping.add(i->first, i->second);
+ Items.erase(i++);
+ } else
+ ++i;
+ }
+
+ /// Removes all clusters for given successor.
+ void removeCase(SuccessorClass *Succ) {
+ for (CaseItemIt i = Items.begin(); i != Items.end();)
+ if (i->second == Succ) {
+ Items.erase(i++);
+ } else
+ ++i;
+ }
+
+ /// Find successor that satisfies given value.
+ SuccessorClass *findSuccessor(const IntTy& Val) {
+ for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
+ if (i->first.isInRange(Val))
+ return i->second;
+ }
+ return 0;
+ }
+
+ /// Calculates the difference between this mapping and RHS.
+ /// THIS without RHS is placed into LExclude,
+ /// RHS without THIS is placed into RExclude,
+ /// THIS intersect RHS is placed into Intersection.
+ void diff(self *LExclude, self *Intersection, self *RExclude,
+ const self& RHS) {
+
+ DiffStateMachine Machine(LExclude, Intersection, RExclude);
+
+ CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
+ while (L != Items.end() && R != RHS.Items.end()) {
+ const Cluster &LCluster = *L;
+ const RangeEx &LRange = LCluster.first;
+ const Cluster &RCluster = *R;
+ const RangeEx &RRange = RCluster.first;
+
+ if (LRange.getHigh() < RRange.getLow()) {
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ Machine.onLClose(LRange.getHigh());
+ ++L;
+ continue;
+ }
+
+ if (LRange.getLow() > RRange.getHigh()) {
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ Machine.onRClose(RRange.getHigh());
+ ++R;
+ continue;
+ }
+
+ if (LRange.getLow() < RRange.getLow()) {
+ // May be opened in previous iteration.
+ if (!Machine.isLOpened())
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ }
+ else if (RRange.getLow() < LRange.getLow()) {
+ if (!Machine.isROpened())
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ }
+ else
+ Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
+
+ if (LRange.getHigh() < RRange.getHigh()) {
+ Machine.onLClose(LRange.getHigh());
+ ++L;
+ while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
+ Machine.onLOpen(L->first.getLow(), L->second);
+ Machine.onLClose(L->first.getHigh());
+ ++L;
+ }
+ }
+ else if (RRange.getHigh() < LRange.getHigh()) {
+ Machine.onRClose(RRange.getHigh());
+ ++R;
+ while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
+ Machine.onROpen(R->first.getLow(), R->second);
+ Machine.onRClose(R->first.getHigh());
+ ++R;
+ }
+ }
+ else {
+ Machine.onLRClose(LRange.getHigh());
+ ++L;
+ ++R;
+ }
+ }
+
+ if (L != Items.end()) {
+ if (Machine.isLOpened()) {
+ Machine.onLClose(L->first.getHigh());
+ ++L;
+ }
+ if (LExclude)
+ while (L != Items.end()) {
+ LExclude->add(L->first, L->second);
+ ++L;
+ }
+ } else if (R != RHS.Items.end()) {
+ if (Machine.isROpened()) {
+ Machine.onRClose(R->first.getHigh());
+ ++R;
+ }
+ if (RExclude)
+ while (R != RHS.Items.end()) {
+ RExclude->add(R->first, R->second);
+ ++R;
+ }
+ }
+ }
+
+ /// Builds the finalized case objects.
+ void getCases(Cases& TheCases, bool PreventMerging = false) {
+ //FIXME: PreventMerging is a temporary parameter.
+ //Currently a set of passes is still knows nothing about
+ //switches with case ranges, and if these passes meet switch
+ //with complex case that crashs the application.
+ if (PreventMerging) {
+ for (RangeIterator i = this->begin(); i != this->end(); ++i) {
+ RangesCollection SingleRange;
+ SingleRange.push_back(i->first);
+ TheCases.push_back(std::make_pair(i->second,
+ IntegersSubsetTy(SingleRange)));
+ }
+ return;
+ }
+ CRSMap TheCRSMap;
+ for (RangeIterator i = this->begin(); i != this->end(); ++i)
+ TheCRSMap[i->second].push_back(i->first);
+ for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
+ TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
+ }
+
+ /// Builds the finalized case objects ignoring successor values, as though
+ /// all ranges belongs to the same successor.
+ IntegersSubsetTy getCase() {
+ RangesCollection Ranges;
+ for (RangeIterator i = this->begin(); i != this->end(); ++i)
+ Ranges.push_back(i->first);
+ return IntegersSubsetTy(Ranges);
+ }
+
+ /// Returns pointer to value of case if it is single-numbered or 0
+ /// in another case.
+ const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
+ const IntTy* Res = 0;
+ for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
+ if (i->second == Succ) {
+ if (!i->first.isSingleNumber())
+ return 0;
+ if (Res)
+ return 0;
+ else
+ Res = &(i->first.getLow());
+ }
+ return Res;
+ }
+
+ /// Returns true if there is no ranges and values inside.
+ bool empty() const { return Items.empty(); }
+
+ void clear() {
+ Items.clear();
+ // Don't reset Sorted flag:
+ // 1. For empty mapping it matters nothing.
+ // 2. After first item will added Sorted flag will cleared.
+ }
+
+ // Returns number of clusters
+ unsigned size() const {
+ return Items.size();
+ }
+
+ RangeIterator begin() { return Items.begin(); }
+ RangeIterator end() { return Items.end(); }
+};
+
+class BasicBlock;
+typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
+
+}
+
+#endif /* CRSBUILDER_H_ */
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
new file mode 100644
index 000000000000..00c7eeaebcbb
--- /dev/null
+++ b/include/llvm/Support/LEB128.h
@@ -0,0 +1,58 @@
+//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some utility functions for encoding SLEB128 and
+// ULEB128 values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_LEB128_H
+#define LLVM_SYSTEM_LEB128_H
+
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+
+/// Utility function to encode a SLEB128 value.
+static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
+ bool More;
+ do {
+ uint8_t Byte = Value & 0x7f;
+ // NOTE: this assumes that this signed shift is an arithmetic right shift.
+ Value >>= 7;
+ More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
+ ((Value == -1) && ((Byte & 0x40) != 0))));
+ if (More)
+ Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ OS << char(Byte);
+ } while (More);
+}
+
+/// Utility function to encode a ULEB128 value.
+static inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
+ unsigned Padding = 0) {
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ if (Value != 0 || Padding != 0)
+ Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ OS << char(Byte);
+ } while (Value != 0);
+
+ // Pad with 0x80 and emit a null byte at the end.
+ if (Padding != 0) {
+ for (; Padding != 1; --Padding)
+ OS << '\x80';
+ OS << '\x00';
+ }
+}
+
+} // namespace llvm
+
+#endif // LLVM_SYSTEM_LEB128_H
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 44a7a791c522..7f28c3f50021 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -174,50 +174,50 @@ namespace llvm {
RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
- RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
+ RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
- RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+ RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
- RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
- RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
+ RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
+ RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
BindTypePointer = 1u, // BIND_TYPE_POINTER
- BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
- BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
+ BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
+ BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
- BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
+ BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
- BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
- BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
- BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
+ BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
+ BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+ BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
- BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
- BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
+ BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
+ BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
- ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
+ ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
@@ -227,7 +227,7 @@ namespace llvm {
// Constant masks for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
NlistMaskStab = 0xe0, // N_STAB
- NlistMaskPrivateExternal = 0x10, // N_PEXT
+ NlistMaskPrivateExternal = 0x10, // N_PEXT
NlistMaskType = 0x0e, // N_TYPE
NlistMaskExternal = 0x01, // N_EXT
@@ -249,35 +249,35 @@ namespace llvm {
// Constant values for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
- StabGlobalSymbol = 0x20u, // N_GSYM
- StabFunctionName = 0x22u, // N_FNAME
- StabFunction = 0x24u, // N_FUN
- StabStaticSymbol = 0x26u, // N_STSYM
- StabLocalCommon = 0x28u, // N_LCSYM
+ StabGlobalSymbol = 0x20u, // N_GSYM
+ StabFunctionName = 0x22u, // N_FNAME
+ StabFunction = 0x24u, // N_FUN
+ StabStaticSymbol = 0x26u, // N_STSYM
+ StabLocalCommon = 0x28u, // N_LCSYM
StabBeginSymbol = 0x2Eu, // N_BNSYM
- StabSourceFileOptions = 0x3Cu, // N_OPT
- StabRegisterSymbol = 0x40u, // N_RSYM
- StabSourceLine = 0x44u, // N_SLINE
+ StabSourceFileOptions = 0x3Cu, // N_OPT
+ StabRegisterSymbol = 0x40u, // N_RSYM
+ StabSourceLine = 0x44u, // N_SLINE
StabEndSymbol = 0x4Eu, // N_ENSYM
- StabStructureType = 0x60u, // N_SSYM
- StabSourceFileName = 0x64u, // N_SO
- StabObjectFileName = 0x66u, // N_OSO
- StabLocalSymbol = 0x80u, // N_LSYM
- StabBeginIncludeFileName = 0x82u, // N_BINCL
- StabIncludeFileName = 0x84u, // N_SOL
+ StabStructureType = 0x60u, // N_SSYM
+ StabSourceFileName = 0x64u, // N_SO
+ StabObjectFileName = 0x66u, // N_OSO
+ StabLocalSymbol = 0x80u, // N_LSYM
+ StabBeginIncludeFileName = 0x82u, // N_BINCL
+ StabIncludeFileName = 0x84u, // N_SOL
StabCompilerParameters = 0x86u, // N_PARAMS
StabCompilerVersion = 0x88u, // N_VERSION
StabCompilerOptLevel = 0x8Au, // N_OLEVEL
- StabParameter = 0xA0u, // N_PSYM
- StabEndIncludeFile = 0xA2u, // N_EINCL
- StabAlternateEntry = 0xA4u, // N_ENTRY
- StabLeftBracket = 0xC0u, // N_LBRAC
- StabDeletedIncludeFile = 0xC2u, // N_EXCL
- StabRightBracket = 0xE0u, // N_RBRAC
- StabBeginCommon = 0xE2u, // N_BCOMM
- StabEndCommon = 0xE4u, // N_ECOMM
- StabEndCommonLocal = 0xE8u, // N_ECOML
- StabLength = 0xFEu // N_LENG
+ StabParameter = 0xA0u, // N_PSYM
+ StabEndIncludeFile = 0xA2u, // N_EINCL
+ StabAlternateEntry = 0xA4u, // N_ENTRY
+ StabLeftBracket = 0xC0u, // N_LBRAC
+ StabDeletedIncludeFile = 0xC2u, // N_EXCL
+ StabRightBracket = 0xE0u, // N_RBRAC
+ StabBeginCommon = 0xE2u, // N_BCOMM
+ StabEndCommon = 0xE4u, // N_ECOMM
+ StabEndCommonLocal = 0xE8u, // N_ECOML
+ StabLength = 0xFEu // N_LENG
};
@@ -490,12 +490,12 @@ namespace llvm {
uint32_t nextrel;
uint32_t locreloff;
uint32_t nlocrel;
- };
+ };
struct dylib_table_of_contents {
uint32_t symbol_index;
uint32_t module_index;
- };
+ };
struct dylib_module {
uint32_t module_name;
@@ -511,7 +511,7 @@ namespace llvm {
uint32_t ninit_nterm;
uint32_t objc_module_info_addr;
uint32_t objc_module_info_size;
- };
+ };
struct dylib_module_64 {
uint32_t module_name;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index d085c94f2adc..4005161320d6 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -414,14 +414,14 @@ int IsInf(double d);
/// MinAlign - A and B are either alignments or offsets. Return the minimum
/// alignment that may be assumed after adding the two together.
-static 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.
return (A | B) & -(A | B);
}
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
/// that is strictly greater than A. Returns zero on overflow.
-static inline uint64_t NextPowerOf2(uint64_t A) {
+inline uint64_t NextPowerOf2(uint64_t A) {
A |= (A >> 1);
A |= (A >> 2);
A |= (A >> 4);
diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h
index 6d38c9571558..8d797097a840 100644
--- a/include/llvm/Support/PathV2.h
+++ b/include/llvm/Support/PathV2.h
@@ -47,9 +47,9 @@ namespace path {
/// C:\foo\bar => C:,/,foo,bar
///
class const_iterator {
- StringRef Path; //< The entire path.
- StringRef Component; //< The current component. Not necessarily in Path.
- size_t Position; //< The iterators current position within Path.
+ StringRef Path; ///< The entire path.
+ StringRef Component; ///< The current component. Not necessarily in Path.
+ size_t Position; ///< The iterators current position within Path.
// An end iterator has Position = Path.size() + 1.
friend const_iterator begin(StringRef path);
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index d796b7906d37..088897c903d0 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/Process.h ------------------------------------*- C++ -*-===//
+//===- llvm/Support/Process.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -97,6 +97,10 @@ namespace sys {
/// 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
@@ -142,6 +146,10 @@ namespace sys {
/// 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();
/// @}
};
}
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index d48bfcc30c5b..1bf810b4aaf2 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -24,7 +24,6 @@ class SMLoc {
const char *Ptr;
public:
SMLoc() : Ptr(0) {}
- SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
bool isValid() const { return Ptr != 0; }
@@ -48,7 +47,7 @@ public:
SMLoc Start, End;
SMRange() {}
- SMRange(SMLoc Start, SMLoc End) : Start(Start), End(End) {
+ SMRange(SMLoc St, SMLoc En) : Start(St), End(En) {
assert(Start.isValid() == End.isValid() &&
"Start and end should either both be valid or both be invalid!");
}
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 76967dbf78aa..8949a3a908fd 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -123,7 +123,14 @@ public:
/// FindLineNumber - Find the line number for the specified location in the
/// specified file. This is not a fast method.
- unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
+ unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
+ return getLineAndColumn(Loc, BufferID).first;
+ }
+
+ /// getLineAndColumn - Find the line and column number for the specified
+ /// location in the specified file. This is not a fast method.
+ std::pair<unsigned, unsigned>
+ getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
/// PrintMessage - Emit a message about the specified location with the
/// specified string.
@@ -169,9 +176,9 @@ public:
SMDiagnostic()
: SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
- SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Kind,
+ SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd,
const std::string &Msg)
- : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Kind),
+ : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
// Diagnostic with a location.
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 88081307ac6b..c0be8f130aba 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -108,6 +108,7 @@ namespace llvm {
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI);
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx);
typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
@@ -405,11 +406,12 @@ namespace llvm {
/// createMCCodeEmitter - Create a target specific code emitter.
MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx) const {
if (!MCCodeEmitterCtorFn)
return 0;
- return MCCodeEmitterCtorFn(II, STI, Ctx);
+ return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
}
/// createMCObjectStreamer - Create a target specific MCStreamer.
@@ -510,6 +512,21 @@ namespace llvm {
static const Target *lookupTarget(const std::string &Triple,
std::string &Error);
+ /// lookupTarget - Lookup a target based on an architecture name
+ /// and a target triple. If the architecture name is non-empty,
+ /// then the lookup is done by architecture. Otherwise, the target
+ /// triple is used.
+ ///
+ /// \param ArchName - The architecture to use for finding a target.
+ /// \param TheTriple - The triple to use for finding a target. The
+ /// triple is updated with canonical architecture name if a lookup
+ /// by architecture is done.
+ /// \param Error - On failure, an error string describing why no target was
+ /// found.
+ static const Target *lookupTarget(const std::string &ArchName,
+ Triple &TheTriple,
+ std::string &Error);
+
/// getClosestTargetForJIT - Pick the best target that is compatible with
/// the current host. If no close target can be found, this returns null
/// and sets the Error string to a reason.
@@ -1129,6 +1146,7 @@ namespace llvm {
private:
static MCCodeEmitter *Allocator(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new MCCodeEmitterImpl();
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index 15350a7afff7..62ec90ad24f5 100644
--- a/include/llvm/Support/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -15,6 +15,7 @@
#define LLVM_SYSTEM_THREAD_LOCAL_H
#include "llvm/Support/Threading.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -22,7 +23,15 @@ namespace llvm {
// ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
// YOU SHOULD NEVER USE THIS DIRECTLY.
class ThreadLocalImpl {
- void* data;
+ typedef uint64_t ThreadLocalDataTy;
+ /// \brief Platform-specific thread local data.
+ ///
+ /// This is embedded in the class and we avoid malloc'ing/free'ing it,
+ /// to make this class more safe for use along with CrashRecoveryContext.
+ union {
+ char data[sizeof(ThreadLocalDataTy)];
+ ThreadLocalDataTy align_data;
+ };
public:
ThreadLocalImpl();
virtual ~ThreadLocalImpl();
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index b7210b2063ea..61e21b86ead8 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -110,11 +110,12 @@ protected:
V != DenseMapInfo<Value *>::getTombstoneKey();
}
-private:
+public:
// Callbacks made from Value.
static void ValueIsDeleted(Value *V);
static void ValueIsRAUWd(Value *Old, Value *New);
+private:
// Internal implementation details.
ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
HandleBaseKind getKind() const { return PrevPair.getInt(); }
@@ -367,7 +368,7 @@ protected:
CallbackVH(const CallbackVH &RHS)
: ValueHandleBase(Callback, RHS) {}
- virtual ~CallbackVH();
+ virtual ~CallbackVH() {}
void setValPtr(Value *P) {
ValueHandleBase::operator=(P);
@@ -389,15 +390,13 @@ public:
///
/// All implementations must remove the reference from this object to the
/// Value that's being destroyed.
- virtual void deleted() {
- setValPtr(NULL);
- }
+ virtual void deleted();
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
/// _before_ any of the uses have actually been replaced. If WeakVH were
/// implemented as a CallbackVH, it would use this method to call
/// 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
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 47206b3c6d9d..98910eb7578f 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -130,7 +130,7 @@ public:
void setError(const Twine &Message, Token &Location) const;
bool failed() const;
- virtual void skip() {};
+ virtual void skip() {}
unsigned int getType() const { return TypeID; }
static inline bool classof(const Node *) { return true; }
@@ -336,7 +336,7 @@ public:
enum MappingType {
MT_Block,
MT_Flow,
- MT_Inline //< An inline mapping node is used for "[key: value]".
+ MT_Inline ///< An inline mapping node is used for "[key: value]".
};
MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
@@ -513,37 +513,44 @@ private:
/// @brief Iterator abstraction for Documents over a Stream.
class document_iterator {
public:
- document_iterator() : Doc(NullDoc) {}
- document_iterator(OwningPtr<Document> &D) : Doc(D) {}
+ document_iterator() : Doc(0) {}
+ document_iterator(OwningPtr<Document> &D) : Doc(&D) {}
bool operator ==(const document_iterator &Other) {
- return Doc == Other.Doc;
+ if (isAtEnd() || Other.isAtEnd())
+ return isAtEnd() && Other.isAtEnd();
+
+ return *Doc == *Other.Doc;
}
bool operator !=(const document_iterator &Other) {
return !(*this == Other);
}
document_iterator operator ++() {
- if (!Doc->skip()) {
- Doc.reset(0);
+ assert(Doc != 0 && "incrementing iterator past the end.");
+ if (!(*Doc)->skip()) {
+ Doc->reset(0);
} else {
- Stream &S = Doc->stream;
- Doc.reset(new Document(S));
+ Stream &S = (*Doc)->stream;
+ Doc->reset(new Document(S));
}
return *this;
}
Document &operator *() {
- return *Doc;
+ return *Doc->get();
}
OwningPtr<Document> &operator ->() {
- return Doc;
+ return *Doc;
}
private:
- static OwningPtr<Document> NullDoc;
- OwningPtr<Document> &Doc;
+ bool isAtEnd() const {
+ return Doc == 0 || *Doc == 0;
+ }
+
+ OwningPtr<Document> *Doc;
};
}
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 6c5d4787e0f5..5de749aeae4e 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -230,6 +230,9 @@ public:
/// rather than being put on a pipe or stored in a file.
virtual bool is_displayed() const { return false; }
+ /// This function determines if this stream is displayed and supports colors.
+ virtual bool has_colors() const { return is_displayed(); }
+
//===--------------------------------------------------------------------===//
// Subclass Interface
//===--------------------------------------------------------------------===//
@@ -386,10 +389,12 @@ public:
virtual bool is_displayed() const;
+ virtual bool has_colors() const;
+
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
/// whether an output error has been encountered.
/// This doesn't implicitly flush any pending output. Also, it doesn't
- /// guarantee to detect all errors unless the the stream has been closed.
+ /// guarantee to detect all errors unless the stream has been closed.
bool has_error() const {
return Error;
}
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index a3a551f851f3..7b97547be52a 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -21,6 +21,11 @@
#include <cstddef>
#include <utility>
+#ifndef __has_feature
+#define LLVM_DEFINED_HAS_FEATURE
+#define __has_feature(x) 0
+#endif
+
// This is actually the conforming implementation which works with abstract
// classes. However, enough compilers have trouble with it that most will use
// the one in boost/type_traits/object_traits.hpp. This implementation actually
@@ -58,9 +63,15 @@ struct is_class
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
+#if __has_feature(is_trivially_copyable)
+ // If the compiler supports the is_trivially_copyable trait use it, as it
+ // matches the definition of isPodLike closely.
+ static const bool value = __is_trivially_copyable(T);
+#else
// If we don't know anything else, we can (at least) assume that all non-class
// types are PODs.
static const bool value = !is_class<T>::value;
+#endif
};
// std::pair's are pod-like if their elements are.
@@ -202,4 +213,8 @@ struct conditional<false, T, F> { typedef F type; };
}
+#ifdef LLVM_DEFINED_HAS_FEATURE
+#undef __has_feature
+#endif
+
#endif
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 3aea1aeaead3..a8256b77357c 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1558,12 +1558,14 @@ public:
return I == Defs.end() ? 0 : I->second;
}
void addClass(Record *R) {
- assert(getClass(R->getNameInitAsString()) == 0 && "Class already exists!");
- Classes.insert(std::make_pair(R->getNameInitAsString(), R));
+ bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second;
+ (void)Ins;
+ assert(Ins && "Class already exists");
}
void addDef(Record *R) {
- assert(getDef(R->getNameInitAsString()) == 0 && "Def already exists!");
- Defs.insert(std::make_pair(R->getNameInitAsString(), R));
+ bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second;
+ (void)Ins;
+ assert(Ins && "Record already exists");
}
/// removeClass - Remove, but do not delete, the specified record.
diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h
new file mode 100644
index 000000000000..1dadc76200b0
--- /dev/null
+++ b/include/llvm/TableGen/StringMatcher.h
@@ -0,0 +1,54 @@
+//===- StringMatcher.h - Generate a matcher for input strings ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the StringMatcher class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef STRINGMATCHER_H
+#define STRINGMATCHER_H
+
+#include <vector>
+#include <string>
+#include <utility>
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+ class raw_ostream;
+
+/// StringMatcher - Given a list of strings and code to execute when they match,
+/// output a simple switch tree to classify the input string.
+///
+/// If a match is found, the code in Vals[i].second is executed; control must
+/// not exit this code fragment. If nothing matches, execution falls through.
+///
+class StringMatcher {
+public:
+ typedef std::pair<std::string, std::string> StringPair;
+private:
+ StringRef StrVariableName;
+ const std::vector<StringPair> &Matches;
+ raw_ostream &OS;
+
+public:
+ StringMatcher(StringRef strVariableName,
+ const std::vector<StringPair> &matches, raw_ostream &os)
+ : StrVariableName(strVariableName), Matches(matches), OS(os) {}
+
+ void Emit(unsigned Indent = 0) const;
+
+
+private:
+ bool EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
+ unsigned CharNo, unsigned IndentCount) const;
+};
+
+} // end llvm namespace.
+
+#endif
diff --git a/include/llvm/TableGen/TableGenBackend.h b/include/llvm/TableGen/TableGenBackend.h
index 3ebcd92d0e48..bedf7fb343af 100644
--- a/include/llvm/TableGen/TableGenBackend.h
+++ b/include/llvm/TableGen/TableGenBackend.h
@@ -1,4 +1,4 @@
-//===- llvm/TableGen/TableGenBackend.h - Backend base class -----*- C++ -*-===//
+//===- llvm/TableGen/TableGenBackend.h - Backend utilities ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,36 +7,22 @@
//
//===----------------------------------------------------------------------===//
//
-// The TableGenBackend class is provided as a common interface for all TableGen
-// backends. It provides useful services and an standardized interface.
+// Useful utilities for TableGen backends.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TABLEGEN_TABLEGENBACKEND_H
#define LLVM_TABLEGEN_TABLEGENBACKEND_H
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringRef.h"
namespace llvm {
-class Record;
-class RecordKeeper;
+class raw_ostream;
-struct TableGenBackend {
- virtual void anchor();
- virtual ~TableGenBackend() {}
-
- // run - All TableGen backends should implement the run method, which should
- // be the main entry point.
- virtual void run(raw_ostream &OS) = 0;
-
-
-public: // Useful helper routines...
- /// EmitSourceFileHeader - Output a LLVM style file header to the specified
- /// ostream.
- void EmitSourceFileHeader(StringRef Desc, raw_ostream &OS) const;
-
-};
+/// emitSourceFileHeader - Output a LLVM style file header to the specified
+/// raw_ostream.
+void emitSourceFileHeader(StringRef Desc, raw_ostream &OS);
} // End llvm namespace
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index fa1ec5594522..24be2b10416c 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -64,18 +64,6 @@ class Register<string n, list<string> altNames = []> {
// register.
list<RegAltNameIndex> RegAltNameIndices = [];
- // CompositeIndices - Specify subreg indices that don't correspond directly to
- // a register in SubRegs and are not inherited. The following formats are
- // supported:
- //
- // (a) Identity - Reg:a == Reg
- // (a b) Alias - Reg:a == Reg:b
- // (a b,c) Composite - Reg:a == (Reg:b):c
- //
- // This can be used to disambiguate a sub-sub-register that exists in more
- // than one subregister and other weird stuff.
- list<dag> CompositeIndices = [];
-
// DwarfNumbers - Numbers used internally by gcc/gdb to identify the register.
// These values can be determined by locating the <target>.h file in the
// directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
@@ -96,6 +84,9 @@ class Register<string n, list<string> altNames = []> {
// x86 register AX is covered by its sub-registers AL and AH, but EAX is not
// covered by its sub-register AX.
bit CoveredBySubRegs = 0;
+
+ // HWEncoding - The target specific hardware encoding for this register.
+ bits<16> HWEncoding = 0;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
@@ -108,13 +99,20 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
}
+// DAGOperand - An empty base class that unifies RegisterClass's and other forms
+// of Operand's that are legal as type qualifiers in DAG patterns. This should
+// only ever be used for defining multiclasses that are polymorphic over both
+// RegisterClass's and other Operand's.
+class DAGOperand { }
+
// RegisterClass - Now that all of the registers are defined, and aliases
// between registers are defined, specify which registers belong to which
// register classes. This also defines the default allocation order of
// registers by register allocators.
//
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
- dag regList, RegAltNameIndex idx = NoRegAltName> {
+ dag regList, RegAltNameIndex idx = NoRegAltName>
+ : DAGOperand {
string Namespace = namespace;
// RegType - Specify the list ValueType of the registers in this register
@@ -151,10 +149,6 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// a valid alternate name for the given index.
RegAltNameIndex altNameIndex = idx;
- // SubRegClasses - Specify the register class of subregisters as a list of
- // dags: (RegClass SubRegIndex, SubRegindex, ...)
- list<dag> SubRegClasses = [];
-
// isAllocatable - Specify that the register class can be used for virtual
// registers and register allocation. Some register classes are only used to
// model instruction operand constraints, and should have isAllocatable = 0.
@@ -192,7 +186,8 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// also in the second set.
//
// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
-// numbered registers.
+// numbered registers. Takes an optional 4th operand which is a stride to use
+// when generating the sequence.
//
// (shl GPR, 4) - Remove the first N elements.
//
@@ -245,9 +240,6 @@ class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> {
// SubRegIndices - N SubRegIndex instances. This provides the names of the
// sub-registers in the synthesized super-registers.
list<SubRegIndex> SubRegIndices = Indices;
-
- // Compose sub-register indices like in a normal Register.
- list<dag> CompositeIndices = [];
}
@@ -402,6 +394,13 @@ class Instruction {
string AsmMatchConverter = "";
+ /// TwoOperandAliasConstraint - Enable TableGen to auto-generate a
+ /// two-operand matcher inst-alias for a three operand instruction.
+ /// For example, the arm instruction "add r3, r3, r5" can be written
+ /// as "add r3, r5". The constraint is of the same form as a tied-operand
+ /// constraint. For example, "$Rn = $Rd".
+ string TwoOperandAliasConstraint = "";
+
///@}
}
@@ -431,6 +430,10 @@ class Predicate<string cond> {
/// e.g. "ModeThumb,FeatureThumb2" is translated to
/// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
string AssemblerCondString = "";
+
+ /// PredicateName - User-level name to use for the predicate. Mainly for use
+ /// in diagnostics such as missing feature errors in the asm matcher.
+ string PredicateName = "";
}
/// NoHonorSignDependentRounding - This predicate is true if support for
@@ -512,6 +515,11 @@ class AsmOperandClass {
/// to immediates or registers and are very instruction specific (as flags to
/// set in a processor register, coprocessor number, ...).
string ParserMethod = ?;
+
+ // The diagnostic type to present when referencing this operand in a
+ // match failure error message. By default, use a generic "invalid operand"
+ // diagnostic. The target AsmParser maps these codes to text.
+ string DiagnosticType = "";
}
def ImmAsmOperand : AsmOperandClass {
@@ -521,7 +529,7 @@ def ImmAsmOperand : AsmOperandClass {
/// Operand Types - These provide the built-in operand types that may be used
/// by a target. Targets can optionally provide their own operand types as
/// needed, though this should not be needed for RISC targets.
-class Operand<ValueType ty> {
+class Operand<ValueType ty> : DAGOperand {
ValueType Type = ty;
string PrintMethod = "printOperand";
string EncoderMethod = "";
@@ -541,7 +549,8 @@ class Operand<ValueType ty> {
AsmOperandClass ParserMatchClass = ImmAsmOperand;
}
-class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand">
+ : DAGOperand {
// RegClass - The register class of the operand.
RegisterClass RegClass = regclass;
// PrintMethod - The target method to call to print register operands of
@@ -729,7 +738,7 @@ class AsmParser {
def DefaultAsmParser : AsmParser;
//===----------------------------------------------------------------------===//
-// AsmParserVariant - Subtargets can have multiple different assembly parsers
+// AsmParserVariant - Subtargets can have multiple different assembly parsers
// (e.g. AT&T vs Intel syntax on X86 for example). This class can be
// implemented by targets to describe such variants.
//
@@ -754,9 +763,10 @@ def DefaultAsmParserVariant : AsmParserVariant;
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases.
-class AssemblerPredicate<string cond> {
+class AssemblerPredicate<string cond, string name = ""> {
bit AssemblerMatcherPredicate = 1;
string AssemblerCondString = cond;
+ string PredicateName = name;
}
/// TokenAlias - This class allows targets to define assembler token
@@ -861,7 +871,7 @@ class Target {
// AssemblyParsers - The AsmParser instances available for this target.
list<AsmParser> AssemblyParsers = [DefaultAsmParser];
- /// AssemblyParserVariants - The AsmParserVariant instances available for
+ /// AssemblyParserVariants - The AsmParserVariant instances available for
/// this target.
list<AsmParserVariant> AssemblyParserVariants = [DefaultAsmParserVariant];
@@ -909,6 +919,10 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
//
string Name = n;
+ // SchedModel - The machine model for scheduling and instruction cost.
+ //
+ SchedMachineModel SchedModel = NoSchedModel;
+
// ProcItin - The scheduling information for the target processor.
//
ProcessorItineraries ProcItin = pi;
@@ -917,6 +931,14 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
list<SubtargetFeature> Features = f;
}
+// ProcessorModel allows subtargets to specify the more general
+// SchedMachineModel instead if a ProcessorItinerary. Subtargets will
+// gradually move to this newer form.
+class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f>
+ : Processor<n, NoItineraries, f> {
+ let SchedModel = m;
+}
+
//===----------------------------------------------------------------------===//
// Pull in the common support for calling conventions.
//
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index a6251e7d3345..f8cebefb0eae 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -36,16 +36,16 @@ namespace ISD {
static const uint64_t ByValOffs = 4;
static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
static const uint64_t NestOffs = 5;
- static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment
+ static const uint64_t ByValAlign = 0xFULL << 6; ///< Struct alignment
static const uint64_t ByValAlignOffs = 6;
static const uint64_t Split = 1ULL << 10;
static const uint64_t SplitOffs = 10;
static const uint64_t OrigAlign = 0x1FULL<<27;
static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size
+ static const uint64_t ByValSize = 0xffffffffULL << 32; ///< Struct size
static const uint64_t ByValSizeOffs = 32;
- static const uint64_t One = 1ULL; //< 1 of this type, for shifts
+ static const uint64_t One = 1ULL; ///< 1 of this type, for shifts
uint64_t Flags;
public:
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index d116f392fb31..4f94ab751cb6 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -53,10 +53,10 @@ enum AlignTypeEnum {
/// @note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly.
struct TargetAlignElem {
- AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum)
- unsigned ABIAlign; //< ABI alignment for this type/bitw
- unsigned PrefAlign; //< Pref. alignment for this type/bitw
- uint32_t TypeBitWidth; //< Type bit width
+ AlignTypeEnum AlignType : 8; ///< Alignment type (AlignTypeEnum)
+ unsigned ABIAlign; ///< ABI alignment for this type/bitw
+ unsigned PrefAlign; ///< Pref. alignment for this type/bitw
+ uint32_t TypeBitWidth; ///< Type bit width
/// Initializer
static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h
index 114295e8f985..5e48629cf4d6 100644
--- a/include/llvm/Target/TargetELFWriterInfo.h
+++ b/include/llvm/Target/TargetELFWriterInfo.h
@@ -43,7 +43,8 @@ namespace llvm {
EM_ARM = 40, // ARM
EM_ALPHA = 41, // DEC Alpha
EM_SPARCV9 = 43, // SPARC V9
- EM_X86_64 = 62 // AMD64
+ EM_X86_64 = 62, // AMD64
+ EM_HEXAGON = 164 // Qualcomm Hexagon
};
// ELF File classes
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index d1e380c5602a..a18b0305a94b 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
+#include "llvm/ADT/SmallSet.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -27,6 +28,7 @@ class MachineMemOperand;
class MachineRegisterInfo;
class MDNode;
class MCInst;
+class MCSchedModel;
class SDNode;
class ScheduleHazardRecognizer;
class SelectionDAG;
@@ -57,7 +59,8 @@ public:
/// class constraint for OpNum, or NULL.
const TargetRegisterClass *getRegClass(const MCInstrDesc &TID,
unsigned OpNum,
- const TargetRegisterInfo *TRI) const;
+ const TargetRegisterInfo *TRI,
+ const MachineFunction &MF) const;
/// isTriviallyReMaterializable - Return true if the instruction is trivially
/// rematerializable, meaning it has no side effects and requires no operands
@@ -185,14 +188,6 @@ public:
const MachineInstr *Orig,
const TargetRegisterInfo &TRI) const = 0;
- /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
- /// two-addrss instruction inserted by two-address pass.
- virtual void scheduleTwoAddrSource(MachineInstr *SrcMI,
- MachineInstr *UseMI,
- const TargetRegisterInfo &TRI) const {
- // Do nothing.
- }
-
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like
/// MachineFunction::CloneMachineInstr(), but the target may update operands
/// that are required to be unique.
@@ -319,7 +314,7 @@ public:
/// being executed is given by Probability, and Confidence is a measure
/// of our confidence that it will be properly predicted.
virtual
- bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
unsigned ExtraPredCycles,
const BranchProbability &Probability) const {
return false;
@@ -347,7 +342,7 @@ public:
/// Probability, and Confidence is a measure of our confidence that it
/// will be properly predicted.
virtual bool
- isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
const BranchProbability &Probability) const {
return false;
}
@@ -368,6 +363,56 @@ public:
return false;
}
+ /// canInsertSelect - Return true if it is possible to insert a select
+ /// instruction that chooses between TrueReg and FalseReg based on the
+ /// condition code in Cond.
+ ///
+ /// When successful, also return the latency in cycles from TrueReg,
+ /// FalseReg, and Cond to the destination register. The Cond latency should
+ /// compensate for a conditional branch being removed. For example, if a
+ /// conditional branch has a 3 cycle latency from the condition code read,
+ /// and a cmov instruction has a 2 cycle latency from the condition code
+ /// read, CondCycles should be returned as -1.
+ ///
+ /// @param MBB Block where select instruction would be inserted.
+ /// @param Cond Condition returned by AnalyzeBranch.
+ /// @param TrueReg Virtual register to select when Cond is true.
+ /// @param FalseReg Virtual register to select when Cond is false.
+ /// @param CondCycles Latency from Cond+Branch to select output.
+ /// @param TrueCycles Latency from TrueReg to select output.
+ /// @param FalseCycles Latency from FalseReg to select output.
+ virtual bool canInsertSelect(const MachineBasicBlock &MBB,
+ const SmallVectorImpl<MachineOperand> &Cond,
+ unsigned TrueReg, unsigned FalseReg,
+ int &CondCycles,
+ int &TrueCycles, int &FalseCycles) const {
+ return false;
+ }
+
+ /// insertSelect - Insert a select instruction into MBB before I that will
+ /// copy TrueReg to DstReg when Cond is true, and FalseReg to DstReg when
+ /// Cond is false.
+ ///
+ /// This function can only be called after canInsertSelect() returned true.
+ /// The condition in Cond comes from AnalyzeBranch, and it can be assumed
+ /// that the same flags or registers required by Cond are available at the
+ /// insertion point.
+ ///
+ /// @param MBB Block where select instruction should be inserted.
+ /// @param I Insertion point.
+ /// @param DL Source location for debugging.
+ /// @param DstReg Virtual register to be defined by select instruction.
+ /// @param Cond Condition as computed by AnalyzeBranch.
+ /// @param TrueReg Virtual register to copy when Cond is true.
+ /// @param FalseReg Virtual register to copy when Cons is false.
+ virtual void insertSelect(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I, DebugLoc DL,
+ unsigned DstReg,
+ const SmallVectorImpl<MachineOperand> &Cond,
+ unsigned TrueReg, unsigned FalseReg) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
+ }
+
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
@@ -608,6 +653,13 @@ public:
CreateTargetHazardRecognizer(const TargetMachine *TM,
const ScheduleDAG *DAG) const = 0;
+ /// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer
+ /// to use for this target when scheduling the machine instructions before
+ /// register allocation.
+ virtual ScheduleHazardRecognizer*
+ CreateTargetMIHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG *DAG) const = 0;
+
/// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard
/// recognizer to use for this target when scheduling the machine instructions
/// after register allocation.
@@ -615,23 +667,40 @@ public:
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
const ScheduleDAG *DAG) const = 0;
- /// AnalyzeCompare - For a comparison instruction, return the source register
- /// in SrcReg and the value it compares against in CmpValue. Return true if
- /// the comparison instruction can be analyzed.
- virtual bool AnalyzeCompare(const MachineInstr *MI,
- unsigned &SrcReg, int &Mask, int &Value) const {
+ /// analyzeCompare - For a comparison instruction, return the source registers
+ /// in SrcReg and SrcReg2 if having two register operands, and the value it
+ /// compares against in CmpValue. Return true if the comparison instruction
+ /// can be analyzed.
+ virtual bool analyzeCompare(const MachineInstr *MI,
+ unsigned &SrcReg, unsigned &SrcReg2,
+ int &Mask, int &Value) const {
return false;
}
- /// OptimizeCompareInstr - See if the comparison instruction can be converted
+ /// optimizeCompareInstr - See if the comparison instruction can be converted
/// into something more efficient. E.g., on ARM most instructions can set the
/// flags register, obviating the need for a separate CMP.
- virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr,
- unsigned SrcReg, int Mask, int Value,
+ virtual bool optimizeCompareInstr(MachineInstr *CmpInstr,
+ unsigned SrcReg, unsigned SrcReg2,
+ int Mask, int Value,
const MachineRegisterInfo *MRI) const {
return false;
}
+ /// optimizeLoadInstr - Try to remove the load by folding it to a register
+ /// operand at the use. We fold the load instructions if and only if the
+ /// def and use are in the same BB. We only look at one load and see
+ /// whether it can be folded into MI. FoldAsLoadDefReg is the virtual register
+ /// defined by the load we are trying to fold. DefMI returns the machine
+ /// instruction that defines FoldAsLoadDefReg, and the function returns
+ /// the machine instruction generated due to folding.
+ virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI,
+ const MachineRegisterInfo *MRI,
+ unsigned &FoldAsLoadDefReg,
+ MachineInstr *&DefMI) const {
+ return 0;
+ }
+
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
/// instruction, try to fold the immediate into the use instruction.
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
@@ -640,9 +709,11 @@ public:
}
/// getNumMicroOps - Return the number of u-operations the given machine
- /// instruction will be decoded to on the target cpu.
+ /// instruction will be decoded to on the target cpu. The itinerary's
+ /// IssueWidth is the number of microops that can be dispatched each
+ /// cycle. An instruction with zero microops takes no dispatch resources.
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
- const MachineInstr *MI) const;
+ const MachineInstr *MI) const = 0;
/// isZeroCost - Return true for pseudo instructions that don't consume any
/// machine resources in their current form. These are common cases that the
@@ -652,18 +723,45 @@ public:
return Opcode <= TargetOpcode::COPY;
}
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ SDNode *DefNode, unsigned DefIdx,
+ SDNode *UseNode, unsigned UseIdx) const = 0;
+
/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
/// In most cases, the static scheduling itinerary was enough to determine the
/// operand latency. But it may not be possible for instructions with variable
/// number of defs / uses.
+ ///
+ /// This is a raw interface to the itinerary that may be directly overriden by
+ /// a target. Use computeOperandLatency to get the best estimate of latency.
virtual int getOperandLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx,
- const MachineInstr *UseMI, unsigned UseIdx) const;
-
- virtual int getOperandLatency(const InstrItineraryData *ItinData,
- SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const = 0;
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI,
+ unsigned UseIdx) const = 0;
+
+ /// computeOperandLatency - Compute and return the latency of the given data
+ /// dependent def and use when the operand indices are already known.
+ ///
+ /// FindMin may be set to get the minimum vs. expected latency.
+ unsigned computeOperandLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI, unsigned UseIdx,
+ bool FindMin = false) const;
+
+ /// computeOperandLatency - Compute and return the latency of the given data
+ /// dependent def and use. DefMI must be a valid def. UseMI may be NULL for
+ /// an unknown use. If the subtarget allows, this may or may not need to call
+ /// getOperandLatency().
+ ///
+ /// FindMin may be set to get the minimum vs. expected latency. Minimum
+ /// latency is used for scheduling groups, while expected latency is for
+ /// instruction cost and critical path.
+ unsigned computeOperandLatency(const InstrItineraryData *ItinData,
+ const TargetRegisterInfo *TRI,
+ const MachineInstr *DefMI,
+ const MachineInstr *UseMI,
+ unsigned Reg, bool FindMin) const;
/// getOutputLatency - Compute and return the output dependency latency of a
/// a given pair of defs which both target the same register. This is usually
@@ -677,13 +775,17 @@ public:
/// getInstrLatency - Compute the instruction latency of a given instruction.
/// If the instruction has higher cost when predicated, it's returned via
/// PredCost.
- virtual int getInstrLatency(const InstrItineraryData *ItinData,
- const MachineInstr *MI,
- unsigned *PredCost = 0) const;
+ virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *MI,
+ unsigned *PredCost = 0) const = 0;
virtual int getInstrLatency(const InstrItineraryData *ItinData,
SDNode *Node) const = 0;
+ /// Return the default expected latency for a def based on it's opcode.
+ unsigned defaultDefLatency(const MCSchedModel *SchedModel,
+ const MachineInstr *DefMI) const;
+
/// isHighLatencyDef - Return true if this opcode has high latency to its
/// result.
virtual bool isHighLatencyDef(int opc) const { return false; }
@@ -705,7 +807,7 @@ public:
/// if the target considered it 'low'.
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx) const;
+ const MachineInstr *DefMI, unsigned DefIdx) const = 0;
/// verifyInstruction - Perform target specific instruction verification.
virtual
@@ -862,20 +964,40 @@ public:
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
- using TargetInstrInfo::getOperandLatency;
+
virtual int getOperandLatency(const InstrItineraryData *ItinData,
SDNode *DefNode, unsigned DefIdx,
SDNode *UseNode, unsigned UseIdx) const;
- using TargetInstrInfo::getInstrLatency;
+
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*) const;
virtual ScheduleHazardRecognizer *
+ CreateTargetMIHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG*) const;
+
+ virtual ScheduleHazardRecognizer *
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
const ScheduleDAG*) const;
};
diff --git a/include/llvm/Target/TargetItinerary.td b/include/llvm/Target/TargetItinerary.td
new file mode 100644
index 000000000000..cc74006dc9fe
--- /dev/null
+++ b/include/llvm/Target/TargetItinerary.td
@@ -0,0 +1,136 @@
+//===- TargetItinerary.td - Target Itinierary Description --*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the target-independent scheduling interfaces
+// which should be implemented by each target that uses instruction
+// itineraries for scheduling. Itineraries are details reservation
+// tables for each instruction class. They are most appropriate for
+// in-order machine with complicated scheduling or bundling constraints.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Processor functional unit - These values represent the function units
+// available across all chip sets for the target. Eg., IntUnit, FPUnit, ...
+// These may be independent values for each chip set or may be shared across
+// all chip sets of the target. Each functional unit is treated as a resource
+// during scheduling and has an affect instruction order based on availability
+// during a time interval.
+//
+class FuncUnit;
+
+//===----------------------------------------------------------------------===//
+// Pipeline bypass / forwarding - These values specifies the symbolic names of
+// pipeline bypasses which can be used to forward results of instructions
+// that are forwarded to uses.
+class Bypass;
+def NoBypass : Bypass;
+
+class ReservationKind<bits<1> val> {
+ int Value = val;
+}
+
+def Required : ReservationKind<0>;
+def Reserved : ReservationKind<1>;
+
+//===----------------------------------------------------------------------===//
+// Instruction stage - These values represent a non-pipelined step in
+// the execution of an instruction. Cycles represents the number of
+// discrete time slots needed to complete the stage. Units represent
+// the choice of functional units that can be used to complete the
+// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+// cycles should elapse from the start of this stage to the start of
+// the next stage in the itinerary. For example:
+//
+// A stage is specified in one of two ways:
+//
+// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles
+// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit
+//
+
+class InstrStage<int cycles, list<FuncUnit> units,
+ int timeinc = -1,
+ ReservationKind kind = Required> {
+ int Cycles = cycles; // length of stage in machine cycles
+ list<FuncUnit> Units = units; // choice of functional units
+ int TimeInc = timeinc; // cycles till start of next stage
+ int Kind = kind.Value; // kind of FU reservation
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary - An itinerary represents a sequential series of steps
+// required to complete an instruction. Itineraries are represented as lists of
+// instruction stages.
+//
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary classes - These values represent 'named' instruction
+// itinerary. Using named itineraries simplifies managing groups of
+// instructions across chip sets. An instruction uses the same itinerary class
+// across all chip sets. Thus a new chip set can be added without modifying
+// instruction information.
+//
+class InstrItinClass;
+def NoItinerary : InstrItinClass;
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary data - These values provide a runtime map of an
+// instruction itinerary class (name) to its itinerary data.
+//
+// NumMicroOps represents the number of micro-operations that each instruction
+// in the class are decoded to. If the number is zero, then it means the
+// instruction can decode into variable number of micro-ops and it must be
+// determined dynamically. This directly relates to the itineraries
+// global IssueWidth property, which constrains the number of microops
+// that can issue per cycle.
+//
+// OperandCycles are optional "cycle counts". They specify the cycle after
+// instruction issue the values which correspond to specific operand indices
+// are defined or read. Bypasses are optional "pipeline forwarding pathes", if
+// a def by an instruction is available on a specific bypass and the use can
+// read from the same bypass, then the operand use latency is reduced by one.
+//
+// InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>,
+// InstrStage<1, [A9_AGU]>],
+// [3, 1], [A9_LdBypass]>,
+// InstrItinData<IIC_iMVNr , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>],
+// [1, 1], [NoBypass, A9_LdBypass]>,
+//
+// In this example, the instruction of IIC_iLoadi reads its input on cycle 1
+// (after issue) and the result of the load is available on cycle 3. The result
+// is available via forwarding path A9_LdBypass. If it's used by the first
+// source operand of instructions of IIC_iMVNr class, then the operand latency
+// is reduced by 1.
+class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
+ list<int> operandcycles = [],
+ list<Bypass> bypasses = [], int uops = 1> {
+ InstrItinClass TheClass = Class;
+ int NumMicroOps = uops;
+ list<InstrStage> Stages = stages;
+ list<int> OperandCycles = operandcycles;
+ list<Bypass> Bypasses = bypasses;
+}
+
+//===----------------------------------------------------------------------===//
+// Processor itineraries - These values represent the set of all itinerary
+// classes for a given chip set.
+//
+// Set property values to -1 to use the default.
+// See InstrItineraryProps for comments and defaults.
+class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
+ list<InstrItinData> iid> {
+ list<FuncUnit> FU = fu;
+ list<Bypass> BP = bp;
+ list<InstrItinData> IID = iid;
+}
+
+// NoItineraries - A marker that can be used by processors without schedule
+// info. Subtargets using NoItineraries can bypass the scheduler's
+// expensive HazardRecognizer because no reservation table is needed.
+def NoItineraries : ProcessorItineraries<[], [], []>;
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index c8cacf284d0a..ea2874f440f7 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -18,36 +18,47 @@ namespace llvm {
namespace LibFunc {
enum Func {
+ /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
+ cxa_atexit,
+ /// void __cxa_guard_abort(guard_t *guard);
+ /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
+ cxa_guard_abort,
+ /// int __cxa_guard_acquire(guard_t *guard);
+ cxa_guard_acquire,
+ /// void __cxa_guard_release(guard_t *guard);
+ cxa_guard_release,
+ /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
+ memcpy_chk,
/// double acos(double x);
acos,
- /// long double acosl(long double x);
- acosl,
/// float acosf(float x);
acosf,
+ /// long double acosl(long double x);
+ acosl,
/// double asin(double x);
asin,
- /// long double asinl(long double x);
- asinl,
/// float asinf(float x);
asinf,
+ /// long double asinl(long double x);
+ asinl,
/// double atan(double x);
atan,
- /// long double atanl(long double x);
- atanl,
- /// float atanf(float x);
- atanf,
/// double atan2(double y, double x);
atan2,
- /// long double atan2l(long double y, long double x);
- atan2l,
/// float atan2f(float y, float x);
atan2f,
+ /// long double atan2l(long double y, long double x);
+ atan2l,
+ /// float atanf(float x);
+ atanf,
+ /// long double atanl(long double x);
+ atanl,
/// double ceil(double x);
ceil,
- /// long double ceill(long double x);
- ceill,
/// float ceilf(float x);
ceilf,
+ /// long double ceill(long double x);
+ ceill,
/// double copysign(double x, double y);
copysign,
/// float copysignf(float x, float y);
@@ -56,54 +67,56 @@ namespace llvm {
copysignl,
/// double cos(double x);
cos,
- /// long double cosl(long double x);
- cosl,
/// float cosf(float x);
cosf,
/// double cosh(double x);
cosh,
- /// long double coshl(long double x);
- coshl,
/// float coshf(float x);
coshf,
+ /// long double coshl(long double x);
+ coshl,
+ /// long double cosl(long double x);
+ cosl,
/// double exp(double x);
exp,
- /// long double expl(long double x);
- expl,
- /// float expf(float x);
- expf,
/// double exp2(double x);
exp2,
- /// long double exp2l(long double x);
- exp2l,
/// float exp2f(float x);
exp2f,
+ /// long double exp2l(long double x);
+ exp2l,
+ /// float expf(float x);
+ expf,
+ /// long double expl(long double x);
+ expl,
/// double expm1(double x);
expm1,
- /// long double expm1l(long double x);
- expm1l,
/// float expm1f(float x);
expm1f,
+ /// long double expm1l(long double x);
+ expm1l,
/// double fabs(double x);
fabs,
- /// long double fabsl(long double x);
- fabsl,
/// float fabsf(float x);
fabsf,
+ /// long double fabsl(long double x);
+ fabsl,
+ /// int fiprintf(FILE *stream, const char *format, ...);
+ fiprintf,
/// double floor(double x);
floor,
- /// long double floorl(long double x);
- floorl,
/// float floorf(float x);
floorf,
- /// int fiprintf(FILE *stream, const char *format, ...);
- fiprintf,
+ /// long double floorl(long double x);
+ floorl,
/// double fmod(double x, double y);
fmod,
- /// long double fmodl(long double x, long double y);
- fmodl,
/// float fmodf(float x, float y);
fmodf,
+ /// long double fmodl(long double x, long double y);
+ fmodl,
+ /// int fputc(int c, FILE *stream);
+ fputc,
/// int fputs(const char *s, FILE *stream);
fputs,
/// size_t fwrite(const void *ptr, size_t size, size_t nitems,
@@ -113,28 +126,32 @@ namespace llvm {
iprintf,
/// double log(double x);
log,
- /// long double logl(long double x);
- logl,
- /// float logf(float x);
- logf,
- /// double log2(double x);
- log2,
- /// double long double log2l(long double x);
- log2l,
- /// float log2f(float x);
- log2f,
/// double log10(double x);
log10,
- /// long double log10l(long double x);
- log10l,
/// float log10f(float x);
log10f,
+ /// long double log10l(long double x);
+ log10l,
/// double log1p(double x);
log1p,
- /// long double log1pl(long double x);
- log1pl,
/// float log1pf(float x);
log1pf,
+ /// long double log1pl(long double x);
+ log1pl,
+ /// double log2(double x);
+ log2,
+ /// float log2f(float x);
+ log2f,
+ /// double long double log2l(long double x);
+ log2l,
+ /// float logf(float x);
+ logf,
+ /// long double logl(long double x);
+ logl,
+ /// void *memchr(const void *s, int c, size_t n);
+ memchr,
+ /// int memcmp(const void *s1, const void *s2, size_t n);
+ memcmp,
/// void *memcpy(void *s1, const void *s2, size_t n);
memcpy,
/// void *memmove(void *s1, const void *s2, size_t n);
@@ -155,6 +172,10 @@ namespace llvm {
powf,
/// long double powl(long double x, long double y);
powl,
+ /// int putchar(int c);
+ putchar,
+ /// int puts(const char *s);
+ puts,
/// double rint(double x);
rint,
/// float rintf(float x);
@@ -169,51 +190,58 @@ namespace llvm {
roundl,
/// double sin(double x);
sin,
- /// long double sinl(long double x);
- sinl,
/// float sinf(float x);
sinf,
/// double sinh(double x);
sinh,
- /// long double sinhl(long double x);
- sinhl,
/// float sinhf(float x);
sinhf,
+ /// long double sinhl(long double x);
+ sinhl,
+ /// long double sinl(long double x);
+ sinl,
/// int siprintf(char *str, const char *format, ...);
siprintf,
/// double sqrt(double x);
sqrt,
- /// long double sqrtl(long double x);
- sqrtl,
/// float sqrtf(float x);
sqrtf,
+ /// long double sqrtl(long double x);
+ sqrtl,
+ /// char *strcat(char *s1, const char *s2);
+ strcat,
+ /// char *strchr(const char *s, int c);
+ strchr,
+ /// char *strcpy(char *s1, const char *s2);
+ strcpy,
+ /// size_t strlen(const char *s);
+ strlen,
+ /// char *strncat(char *s1, const char *s2, size_t n);
+ strncat,
+ /// int strncmp(const char *s1, const char *s2, size_t n);
+ strncmp,
+ /// char *strncpy(char *s1, const char *s2, size_t n);
+ strncpy,
+ /// size_t strnlen(const char *s, size_t maxlen);
+ strnlen,
/// double tan(double x);
tan,
- /// long double tanl(long double x);
- tanl,
/// float tanf(float x);
tanf,
/// double tanh(double x);
tanh,
- /// long double tanhl(long double x);
- tanhl,
/// float tanhf(float x);
tanhf,
+ /// long double tanhl(long double x);
+ tanhl,
+ /// long double tanl(long double x);
+ tanl,
/// double trunc(double x);
trunc,
/// float truncf(float x);
truncf,
/// long double truncl(long double x);
truncl,
- /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
- cxa_atexit,
- /// void __cxa_guard_abort(guard_t *guard);
- /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
- cxa_guard_abort,
- /// int __cxa_guard_acquire(guard_t *guard);
- cxa_guard_acquire,
- /// void __cxa_guard_release(guard_t *guard);
- cxa_guard_release,
NumLibFuncs
};
@@ -247,12 +275,41 @@ public:
TargetLibraryInfo(const Triple &T);
explicit TargetLibraryInfo(const TargetLibraryInfo &TLI);
+ /// getLibFunc - Search for a particular function name. If it is one of the
+ /// known library functions, return true and set F to the corresponding value.
+ bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
+
/// has - This function is used by optimizations that want to match on or form
/// a given library function.
bool has(LibFunc::Func F) const {
return getState(F) != Unavailable;
}
+ /// hasOptimizedCodeGen - Return true if the function is both available as
+ /// a builtin and a candidate for optimized code generation.
+ bool hasOptimizedCodeGen(LibFunc::Func F) const {
+ if (getState(F) == Unavailable)
+ return false;
+ switch (F) {
+ default: break;
+ case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl:
+ case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl:
+ case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl:
+ case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl:
+ case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl:
+ case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl:
+ case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
+ case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
+ case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl:
+ case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl:
+ case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l:
+ case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l:
+ case LibFunc::memcmp:
+ return true;
+ }
+ return false;
+ }
+
StringRef getName(LibFunc::Func F) const {
AvailabilityState State = getState(F);
if (State == Unavailable)
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 720c9df99e2b..acf0419510e9 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -25,6 +25,7 @@
#include "llvm/CallingConv.h"
#include "llvm/InlineAsm.h"
#include "llvm/Attributes.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/Support/DebugLoc.h"
@@ -50,6 +51,7 @@ namespace llvm {
template<typename T> class SmallVectorImpl;
class TargetData;
class TargetRegisterClass;
+ class TargetLibraryInfo;
class TargetLoweringObjectFile;
class Value;
@@ -150,6 +152,12 @@ public:
/// that should be avoided.
bool isJumpExpensive() const { return JumpIsExpensive; }
+ /// isPredictableSelectExpensive - Return true if selects are only cheaper
+ /// than branches if the branch is unlikely to be predicted right.
+ bool isPredictableSelectExpensive() const {
+ return predictableSelectIsExpensive;
+ }
+
/// getSetCCResultType - Return the ValueType of the result of SETCC
/// operations. Also used to obtain the target's preferred type for
/// the condition operand of SELECT and BRCOND nodes. In the case of
@@ -358,7 +366,9 @@ public:
/// for it.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const {
if (VT.isExtended()) return Expand;
- assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ // If a target-specific SDNode requires legalization, require the target
+ // to provide custom legalization for it.
+ if (Op > array_lengthof(OpActions[0])) return Custom;
unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
return (LegalizeAction)OpActions[I][Op];
}
@@ -670,6 +680,12 @@ public:
return UseUnderscoreLongJmp;
}
+ /// supportJumpTables - return whether the target can generate code for
+ /// jump tables.
+ bool supportJumpTables() const {
+ return SupportJumpTables;
+ }
+
/// getStackPointerRegisterToSaveRestore - If a physical register, this
/// specifies the register that llvm.savestack/llvm.restorestack should save
/// and restore.
@@ -984,6 +1000,12 @@ protected:
UseUnderscoreLongJmp = Val;
}
+ /// setSupportJumpTables - Indicate whether the target can generate code for
+ /// jump tables.
+ void setSupportJumpTables(bool Val) {
+ SupportJumpTables = Val;
+ }
+
/// setStackPointerRegisterToSaveRestore - If set to a physical register, this
/// specifies the register that llvm.savestack/llvm.restorestack should save
/// and restore.
@@ -1169,7 +1191,7 @@ protected:
ShouldFoldAtomicFences = fold;
}
- /// setInsertFencesForAtomic - Set if the the DAG builder should
+ /// setInsertFencesForAtomic - Set if the DAG builder should
/// automatically insert fences and reduce the order of atomic memory
/// operations to Monotonic.
void setInsertFencesForAtomic(bool fence) {
@@ -1197,11 +1219,6 @@ public:
llvm_unreachable("Not Implemented");
}
- /// LowerCallTo - This function lowers an abstract call to a function into an
- /// actual call. This returns a pair of operands. The first element is the
- /// return value for the function (if RetTy is not VoidTy). The second
- /// element is the outgoing token chain. It calls LowerCall to do the actual
- /// lowering.
struct ArgListEntry {
SDValue Node;
Type* Ty;
@@ -1217,13 +1234,72 @@ public:
isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
};
typedef std::vector<ArgListEntry> ArgListTy;
- std::pair<SDValue, SDValue>
- LowerCallTo(SDValue Chain, Type *RetTy, bool RetSExt, bool RetZExt,
- bool isVarArg, bool isInreg, unsigned NumFixedArgs,
- CallingConv::ID CallConv, bool isTailCall,
- bool doesNotRet, bool isReturnValueUsed,
- SDValue Callee, ArgListTy &Args,
- SelectionDAG &DAG, DebugLoc dl) const;
+
+ /// CallLoweringInfo - This structure contains all information that is
+ /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
+ /// SelectionDAG builder needs to lower a call, and targets will see this
+ /// struct in their LowerCall implementation.
+ 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::SExt)),
+ 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 callee,
+ 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 into an
+ /// actual call. This returns a pair of operands. The first element is the
+ /// return value for the function (if RetTy is not VoidTy). The second
+ /// element is the outgoing token chain. It calls LowerCall to do the actual
+ /// lowering.
+ std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
/// LowerCall - This hook must be implemented to lower calls into the
/// the specified DAG. The outgoing arguments to the call are described
@@ -1232,13 +1308,7 @@ public:
/// InVals array with legal-type return values from the call, and return
/// the resulting token chain value.
virtual SDValue
- LowerCall(SDValue /*Chain*/, SDValue /*Callee*/,
- CallingConv::ID /*CallConv*/, bool /*isVarArg*/,
- bool /*doesNotRet*/, bool &/*isTailCall*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- const SmallVectorImpl<SDValue> &/*OutVals*/,
- const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
- DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
+ LowerCall(CallLoweringInfo &/*CLI*/,
SmallVectorImpl<SDValue> &/*InVals*/) const {
llvm_unreachable("Not Implemented");
}
@@ -1251,7 +1321,7 @@ public:
/// registers. If false is returned, an sret-demotion is performed.
///
virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
- MachineFunction &/*MF*/, bool /*isVarArg*/,
+ MachineFunction &/*MF*/, bool /*isVarArg*/,
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
LLVMContext &/*Context*/) const
{
@@ -1346,7 +1416,8 @@ public:
/// createFastISel - This method returns a target specific FastISel object,
/// or null if the target does not support "fast" ISel.
- virtual FastISel *createFastISel(FunctionLoweringInfo &) const {
+ virtual FastISel *createFastISel(FunctionLoweringInfo &,
+ const TargetLibraryInfo *) const {
return 0;
}
@@ -1602,6 +1673,14 @@ public:
return false;
}
+ /// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster than
+ /// a pair of mul and add instructions. fmuladd intrinsics will be expanded to
+ /// FMAs when this method returns true (and FMAs are legal), otherwise fmuladd
+ /// is expanded to mul + add.
+ virtual bool isFMAFasterThanMulAndAdd(EVT) const {
+ return 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.
@@ -1665,13 +1744,6 @@ private:
const TargetData *TD;
const TargetLoweringObjectFile &TLOF;
- /// We are in the process of implementing a new TypeLegalization action
- /// which is the promotion of vector elements. This feature is under
- /// development. Until this feature is complete, it is only enabled using a
- /// flag. We pass this flag using a member because of circular dep issues.
- /// This member will be removed with the flag once we complete the transition.
- bool mayPromoteElements;
-
/// PointerTy - The type to use for pointers, usually i32 or i64.
///
MVT PointerTy;
@@ -1708,6 +1780,10 @@ private:
/// llvm.longjmp. Defaults to false.
bool UseUnderscoreLongJmp;
+ /// SupportJumpTables - Whether the target can generate code for jumptables.
+ /// If it's not true, then each jumptable must be lowered into if-then-else's.
+ bool SupportJumpTables;
+
/// BooleanContents - Information about the contents of the high-bits in
/// boolean values held in a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
@@ -1875,9 +1951,8 @@ private:
if (NumElts == 1)
return LegalizeKind(TypeScalarizeVector, EltVT);
- // If we allow the promotion of vector elements using a flag,
- // then try to widen vector elements until a legal type is found.
- if (mayPromoteElements && EltVT.isInteger()) {
+ // Try to widen vector elements until a legal type is found.
+ if (EltVT.isInteger()) {
// Vectors with a number of elements that is not a power of two are always
// widened, for example <3 x float> -> <4 x float>.
if (!VT.isPow2VectorType()) {
@@ -2028,14 +2103,14 @@ protected:
/// optimization.
bool benefitFromCodePlacementOpt;
+ /// predictableSelectIsExpensive - Tells the code generator that select is
+ /// more expensive than a branch if the branch is usually predicted right.
+ bool predictableSelectIsExpensive;
+
private:
/// isLegalRC - Return true if the value types that can be represented by the
/// specified register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
-
- /// hasLegalSuperRegRegClasses - Return true if the specified register class
- /// has one or more super-reg register classes that are legal.
- bool hasLegalSuperRegRegClasses(const TargetRegisterClass *RC) const;
};
/// GetReturnInfo - Given an LLVM IR type and return type attributes,
@@ -2043,8 +2118,7 @@ private:
/// the offsets, if the return value is being lowered to memory.
void GetReturnInfo(Type* ReturnType, Attributes attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
- const TargetLowering &TLI,
- SmallVectorImpl<uint64_t> *Offsets = 0);
+ const TargetLowering &TLI);
} // end llvm namespace
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 1a0560478a41..e4bf32bd86c8 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
+#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/StringRef.h"
@@ -247,7 +248,9 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &,
formatted_raw_ostream &,
CodeGenFileType,
- bool /*DisableVerify*/ = true) {
+ bool /*DisableVerify*/ = true,
+ AnalysisID StartAfter = 0,
+ AnalysisID StopAfter = 0) {
return true;
}
@@ -297,7 +300,9 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- bool DisableVerify = true);
+ bool DisableVerify = true,
+ AnalysisID StartAfter = 0,
+ AnalysisID StopAfter = 0);
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a JITCodeEmitter object to handle
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 12a275731536..d1a07d1480b4 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -30,20 +30,28 @@ namespace llvm {
};
}
+ namespace FPOpFusion {
+ enum FPOpFusionMode {
+ Fast, // Enable fusion of FP ops wherever it's profitable.
+ Standard, // Only allow fusion of 'blessed' ops (currently just fmuladd).
+ Strict // Never fuse FP-ops.
+ };
+ }
+
class TargetOptions {
public:
TargetOptions()
: PrintMachineCode(false), NoFramePointerElim(false),
NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false),
- NoExcessFPPrecision(false), UnsafeFPMath(false), NoInfsFPMath(false),
+ UnsafeFPMath(false), NoInfsFPMath(false),
NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
GuaranteedTailCallOpt(false), DisableTailCalls(false),
- StackAlignmentOverride(0), RealignStack(true),
- DisableJumpTables(false), EnableFastISel(false),
+ StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false),
PositionIndependentExecutable(false), EnableSegmentedStacks(false),
- TrapFuncName(""), FloatABIType(FloatABI::Default)
+ UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default),
+ AllowFPOpFusion(FPOpFusion::Standard)
{}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
@@ -74,14 +82,6 @@ namespace llvm {
unsigned LessPreciseFPMADOption : 1;
bool LessPreciseFPMAD() const;
- /// NoExcessFPPrecision - This flag is enabled when the
- /// -disable-excess-fp-precision flag is specified on the command line.
- /// When this flag is off (the default), the code generator is allowed to
- /// produce results that are "more precise" than IEEE allows. This includes
- /// use of FMA-like operations and use of the X86 FP registers without
- /// rounding all over the place.
- unsigned NoExcessFPPrecision : 1;
-
/// UnsafeFPMath - This flag is enabled when the
/// -enable-unsafe-fp-math flag is specified on the command line. When
/// this flag is off (the default), the code generator is not allowed to
@@ -155,10 +155,6 @@ namespace llvm {
/// automatically realigned, if needed.
unsigned RealignStack : 1;
- /// DisableJumpTables - This flag indicates jump tables should not be
- /// generated.
- unsigned DisableJumpTables : 1;
-
/// EnableFastISel - This flag enables fast-path instruction selection
/// which trades away generated code quality in favor of reducing
/// compile time.
@@ -172,6 +168,10 @@ namespace llvm {
unsigned EnableSegmentedStacks : 1;
+ /// UseInitArray - Use .init_array instead of .ctors for static
+ /// constructors.
+ unsigned UseInitArray : 1;
+
/// getTrapFunctionName - If this returns a non-empty string, this means
/// isel should lower Intrinsic::trap to a call to the specified function
/// name instead of an ISD::TRAP node.
@@ -185,6 +185,25 @@ namespace llvm {
/// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
/// Hard presumes that the normal FP ABI is used.
FloatABI::ABIType FloatABIType;
+
+ /// AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
+ /// This controls the creation of fused FP ops that store intermediate
+ /// results in higher precision than IEEE allows (E.g. FMAs).
+ ///
+ /// Fast mode - allows formation of fused FP ops whenever they're
+ /// profitable.
+ /// Standard mode - allow fusion only for 'blessed' FP ops. At present the
+ /// only blessed op is the fmuladd intrinsic. In the future more blessed ops
+ /// may be added.
+ /// Strict mode - allow fusion only if/when it can be proven that the excess
+ /// precision won't effect the result.
+ ///
+ /// Note: This option only controls formation of fused ops by the optimizers.
+ /// Fused operations that are explicitly specified (e.g. FMA via the
+ /// llvm.fma.* intrinsic) will always be honored, regardless of the value of
+ /// this option.
+ FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 6ddd36451b5c..df4d900e4c8e 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -42,9 +42,9 @@ public:
// Instance variables filled by tablegen, do not use!
const MCRegisterClass *MC;
const vt_iterator VTs;
- const unsigned *SubClassMask;
+ const uint32_t *SubClassMask;
+ const uint16_t *SuperRegIndices;
const sc_iterator SuperClasses;
- const sc_iterator SuperRegClasses;
ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&);
/// getID() - Return the register class ID number.
@@ -119,18 +119,6 @@ public:
return I;
}
- /// superregclasses_begin / superregclasses_end - Loop over all of
- /// the superreg register classes of this register class.
- sc_iterator superregclasses_begin() const {
- return SuperRegClasses;
- }
-
- sc_iterator superregclasses_end() const {
- sc_iterator I = SuperRegClasses;
- while (*I != NULL) ++I;
- return I;
- }
-
/// hasSubClass - return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -163,6 +151,18 @@ public:
return SubClassMask;
}
+ /// getSuperRegIndices - Returns a 0-terminated list of sub-register indices
+ /// that project some super-register class into this register class. The list
+ /// has an entry for each Idx such that:
+ ///
+ /// There exists SuperRC where:
+ /// For all Reg in SuperRC:
+ /// this->contains(Reg:Idx)
+ ///
+ const uint16_t *getSuperRegIndices() const {
+ return SuperRegIndices;
+ }
+
/// getSuperClasses - Returns a NULL terminated list of super-classes. The
/// classes are ordered by ID which is also a topological ordering from large
/// to small classes. The list does NOT include the current class.
@@ -301,6 +301,11 @@ public:
const TargetRegisterClass *
getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const;
+ /// getAllocatableClass - Return the maximal subclass of the given register
+ /// class that is alloctable, or NULL.
+ const TargetRegisterClass *
+ getAllocatableClass(const TargetRegisterClass *RC) const;
+
/// getAllocatableSet - Returns a bitset indexed by register number
/// indicating if a register is allocatable or not. If a register class is
/// specified, returns the subset for the class.
@@ -332,9 +337,23 @@ public:
if (regA == regB) return true;
if (isVirtualRegister(regA) || isVirtualRegister(regB))
return false;
- for (const uint16_t *regList = getOverlaps(regA)+1; *regList; ++regList) {
- if (*regList == regB) return true;
- }
+
+ // Regunits are numerically ordered. Find a common unit.
+ MCRegUnitIterator RUA(regA, this);
+ MCRegUnitIterator RUB(regB, this);
+ do {
+ if (*RUA == *RUB) return true;
+ if (*RUA < *RUB) ++RUA;
+ else ++RUB;
+ } while (RUA.isValid() && RUB.isValid());
+ return false;
+ }
+
+ /// hasRegUnit - Returns true if Reg contains RegUnit.
+ bool hasRegUnit(unsigned Reg, unsigned RegUnit) const {
+ for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units)
+ if (*Units == RegUnit)
+ return true;
return false;
}
@@ -346,10 +365,10 @@ public:
/// isSuperRegister - Returns true if regB is a super-register of regA.
///
- bool isSuperRegister(unsigned regA, unsigned regB) const {
- for (const uint16_t *regList = getSuperRegisters(regA); *regList;++regList){
- if (*regList == regB) return true;
- }
+ bool isSuperRegister(unsigned RegA, unsigned RegB) const {
+ for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
+ if (*I == RegB)
+ return true;
return false;
}
@@ -416,7 +435,7 @@ public:
/// TableGen will synthesize missing A sub-classes.
virtual const TargetRegisterClass *
getMatchingSuperRegClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B, unsigned Idx) const =0;
+ const TargetRegisterClass *B, unsigned Idx) const;
/// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
/// supports the sub-register index Idx.
@@ -431,7 +450,10 @@ public:
///
/// TableGen will synthesize missing RC sub-classes.
virtual const TargetRegisterClass *
- getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0;
+ getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
+ assert(Idx == 0 && "Target has no sub-registers");
+ return RC;
+ }
/// composeSubRegIndices - Return the subregister index you get from composing
/// two subregister indices.
@@ -450,6 +472,34 @@ public:
return b;
}
+ /// getCommonSuperRegClass - Find a common super-register class if it exists.
+ ///
+ /// Find a register class, SuperRC and two sub-register indices, PreA and
+ /// PreB, such that:
+ ///
+ /// 1. PreA + SubA == PreB + SubB (using composeSubRegIndices()), and
+ ///
+ /// 2. For all Reg in SuperRC: Reg:PreA in RCA and Reg:PreB in RCB, and
+ ///
+ /// 3. SuperRC->getSize() >= max(RCA->getSize(), RCB->getSize()).
+ ///
+ /// SuperRC will be chosen such that no super-class of SuperRC satisfies the
+ /// requirements, and there is no register class with a smaller spill size
+ /// that satisfies the requirements.
+ ///
+ /// SubA and SubB must not be 0. Use getMatchingSuperRegClass() instead.
+ ///
+ /// Either of the PreA and PreB sub-register indices may be returned as 0. In
+ /// that case, the returned register class will be a sub-class of the
+ /// corresponding argument register class.
+ ///
+ /// The function returns NULL if no register class can be found.
+ ///
+ const TargetRegisterClass*
+ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
+ const TargetRegisterClass *RCB, unsigned SubB,
+ unsigned &PreA, unsigned &PreB) const;
+
//===--------------------------------------------------------------------===//
// Register Class Information
//
@@ -479,7 +529,8 @@ public:
/// getPointerRegClass - Returns a TargetRegisterClass used for pointer
/// values. If a target supports multiple different pointer register classes,
/// kind specifies which one is indicated.
- virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const {
+ virtual const TargetRegisterClass *
+ getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const {
llvm_unreachable("Target didn't implement getPointerRegClass!");
}
@@ -515,13 +566,16 @@ public:
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(
const TargetRegisterClass *RC) const = 0;
/// Get the number of dimensions of register pressure.
virtual unsigned getNumRegPressureSets() const = 0;
+ /// Get the name of this register unit pressure set.
+ virtual const char *getRegPressureSetName(unsigned Idx) const = 0;
+
/// Get the register unit pressure limit for this dimension.
/// This limit must be adjusted dynamically for reserved registers.
virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
@@ -609,6 +663,12 @@ public:
return false;
}
+ /// trackLivenessAfterRegAlloc - returns true if the live-ins should be tracked
+ /// after register allocation.
+ virtual bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
+ return false;
+ }
+
/// needsStackRealignment - true if storage within the function requires the
/// stack pointer to be aligned more than the normal calling convention calls
/// for.
@@ -708,6 +768,62 @@ public:
};
+//===----------------------------------------------------------------------===//
+// SuperRegClassIterator
+//===----------------------------------------------------------------------===//
+//
+// Iterate over the possible super-registers for a given register class. The
+// iterator will visit a list of pairs (Idx, Mask) corresponding to the
+// possible classes of super-registers.
+//
+// Each bit mask will have at least one set bit, and each set bit in Mask
+// corresponds to a SuperRC such that:
+//
+// For all Reg in SuperRC: Reg:Idx is in RC.
+//
+// The iterator can include (O, RC->getSubClassMask()) as the first entry which
+// also satisfies the above requirement, assuming Reg:0 == Reg.
+//
+class SuperRegClassIterator {
+ const unsigned RCMaskWords;
+ unsigned SubReg;
+ const uint16_t *Idx;
+ const uint32_t *Mask;
+
+public:
+ /// Create a SuperRegClassIterator that visits all the super-register classes
+ /// of RC. When IncludeSelf is set, also include the (0, sub-classes) entry.
+ SuperRegClassIterator(const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI,
+ bool IncludeSelf = false)
+ : RCMaskWords((TRI->getNumRegClasses() + 31) / 32),
+ SubReg(0),
+ Idx(RC->getSuperRegIndices()),
+ Mask(RC->getSubClassMask()) {
+ if (!IncludeSelf)
+ ++*this;
+ }
+
+ /// Returns true if this iterator is still pointing at a valid entry.
+ bool isValid() const { return Idx; }
+
+ /// Returns the current sub-register index.
+ unsigned getSubReg() const { return SubReg; }
+
+ /// Returns the bit mask if register classes that getSubReg() projects into
+ /// RC.
+ const uint32_t *getMask() const { return Mask; }
+
+ /// Advance iterator to the next entry.
+ void operator++() {
+ assert(isValid() && "Cannot move iterator past end.");
+ Mask += RCMaskWords;
+ SubReg = *Idx++;
+ if (!SubReg)
+ Idx = 0;
+ }
+};
+
// This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const {
@@ -742,6 +858,29 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
return OS;
}
+/// PrintRegUnit - Helper class for printing register units on a raw_ostream.
+///
+/// Register units are named after their root registers:
+///
+/// AL - Single root.
+/// FP0~ST7 - Dual roots.
+///
+/// Usage: OS << PrintRegUnit(Unit, TRI) << '\n';
+///
+class PrintRegUnit {
+ const TargetRegisterInfo *TRI;
+ unsigned Unit;
+public:
+ PrintRegUnit(unsigned unit, const TargetRegisterInfo *tri)
+ : TRI(tri), Unit(unit) {}
+ void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) {
+ PR.print(OS);
+ return OS;
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 97ea82ab9e3d..4dc488dbaece 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -1,10 +1,10 @@
//===- TargetSchedule.td - Target Independent Scheduling ---*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent scheduling interfaces which should
@@ -12,119 +12,30 @@
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Processor functional unit - These values represent the function units
-// available across all chip sets for the target. Eg., IntUnit, FPUnit, ...
-// These may be independent values for each chip set or may be shared across
-// all chip sets of the target. Each functional unit is treated as a resource
-// during scheduling and has an affect instruction order based on availability
-// during a time interval.
-//
-class FuncUnit;
-
-//===----------------------------------------------------------------------===//
-// Pipeline bypass / forwarding - These values specifies the symbolic names of
-// pipeline bypasses which can be used to forward results of instructions
-// that are forwarded to uses.
-class Bypass;
-def NoBypass : Bypass;
-
-class ReservationKind<bits<1> val> {
- int Value = val;
-}
-
-def Required : ReservationKind<0>;
-def Reserved : ReservationKind<1>;
+include "llvm/Target/TargetItinerary.td"
-//===----------------------------------------------------------------------===//
-// Instruction stage - These values represent a non-pipelined step in
-// the execution of an instruction. Cycles represents the number of
-// discrete time slots needed to complete the stage. Units represent
-// the choice of functional units that can be used to complete the
-// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
-// cycles should elapse from the start of this stage to the start of
-// the next stage in the itinerary. For example:
-//
-// A stage is specified in one of two ways:
-//
-// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles
-// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit
+// The SchedMachineModel is defined by subtargets for three categories of data:
+// 1) Basic properties for coarse grained instruction cost model.
+// 2) Scheduler Read/Write resources for simple per-opcode cost model.
+// 3) Instruction itineraties for detailed reservation tables.
//
+// Default values for basic properties are defined in MCSchedModel. "-1"
+// indicates that the property is not overriden by the target description.
+class SchedMachineModel {
+ int IssueWidth = -1; // Max instructions that may be scheduled per cycle.
+ int MinLatency = -1; // Determines which instrucions are allowed in a group.
+ // (-1) inorder (0) ooo, (1): inorder +var latencies.
+ int LoadLatency = -1; // Cycles for loads to access the cache.
+ int HighLatency = -1; // Approximation of cycles for "high latency" ops.
+ int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
-class InstrStage<int cycles, list<FuncUnit> units,
- int timeinc = -1,
- ReservationKind kind = Required> {
- int Cycles = cycles; // length of stage in machine cycles
- list<FuncUnit> Units = units; // choice of functional units
- int TimeInc = timeinc; // cycles till start of next stage
- int Kind = kind.Value; // kind of FU reservation
-}
+ ProcessorItineraries Itineraries = NoItineraries;
-//===----------------------------------------------------------------------===//
-// Instruction itinerary - An itinerary represents a sequential series of steps
-// required to complete an instruction. Itineraries are represented as lists of
-// instruction stages.
-//
-
-//===----------------------------------------------------------------------===//
-// Instruction itinerary classes - These values represent 'named' instruction
-// itinerary. Using named itineraries simplifies managing groups of
-// instructions across chip sets. An instruction uses the same itinerary class
-// across all chip sets. Thus a new chip set can be added without modifying
-// instruction information.
-//
-// NumMicroOps represents the number of micro-operations that each instruction
-// in the class are decoded to. If the number is zero, then it means the
-// instruction can decode into variable number of micro-ops and it must be
-// determined dynamically.
-//
-class InstrItinClass<int ops = 1> {
- int NumMicroOps = ops;
+ bit NoModel = 0; // Special tag to indicate missing machine model.
}
-def NoItinerary : InstrItinClass;
-//===----------------------------------------------------------------------===//
-// Instruction itinerary data - These values provide a runtime map of an
-// instruction itinerary class (name) to its itinerary data.
-//
-// OperandCycles are optional "cycle counts". They specify the cycle after
-// instruction issue the values which correspond to specific operand indices
-// are defined or read. Bypasses are optional "pipeline forwarding pathes", if
-// a def by an instruction is available on a specific bypass and the use can
-// read from the same bypass, then the operand use latency is reduced by one.
-//
-// InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>,
-// InstrStage<1, [A9_AGU]>],
-// [3, 1], [A9_LdBypass]>,
-// InstrItinData<IIC_iMVNr , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>],
-// [1, 1], [NoBypass, A9_LdBypass]>,
-//
-// In this example, the instruction of IIC_iLoadi reads its input on cycle 1
-// (after issue) and the result of the load is available on cycle 3. The result
-// is available via forwarding path A9_LdBypass. If it's used by the first
-// source operand of instructions of IIC_iMVNr class, then the operand latency
-// is reduced by 1.
-class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
- list<int> operandcycles = [],
- list<Bypass> bypasses = []> {
- InstrItinClass TheClass = Class;
- list<InstrStage> Stages = stages;
- list<int> OperandCycles = operandcycles;
- list<Bypass> Bypasses = bypasses;
-}
-
-//===----------------------------------------------------------------------===//
-// Processor itineraries - These values represent the set of all itinerary
-// classes for a given chip set.
-//
-class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
- list<InstrItinData> iid> {
- list<FuncUnit> FU = fu;
- list<Bypass> BP = bp;
- list<InstrItinData> IID = iid;
+def NoSchedModel : SchedMachineModel {
+ let NoModel = 1;
}
-// NoItineraries - A marker that can be used by processors without schedule
-// info.
-def NoItineraries : ProcessorItineraries<[], [], []>;
-
+// TODO: Define classes for processor and scheduler resources.
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index f55cf0e6306c..3f81c06bc0b6 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -404,11 +404,16 @@ def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
+def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone,
+ [SDNPHasChain, SDNPSideEffect]>;
def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore,
SDNPMemOperand]>;
+def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf,
+ [SDNPHasChain, SDNPSideEffect]>;
+
def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier,
[SDNPHasChain, SDNPSideEffect]>;
@@ -593,6 +598,13 @@ def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
+// null_frag - The null pattern operator is used in multiclass instantiations
+// which accept an SDPatternOperator for use in matching patterns for internal
+// definitions. When expanding a pattern, if the null fragment is referenced
+// in the expansion, the pattern is discarded and it is as-if '[]' had been
+// specified. This allows multiclasses to have the isel patterns be optional.
+def null_frag : SDPatternOperator;
+
// load fragments.
def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index bbf3a69d246d..4b0c448acfce 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -38,6 +38,13 @@ ModulePass *createAddressSanitizerPass();
// Insert ThreadSanitizer (race detection) instrumentation
FunctionPass *createThreadSanitizerPass();
+
+// BoundsChecking - This pass instruments the code to perform run-time bounds
+// checking on loads, stores, and other memory intrinsics.
+// Penalty is the maximum run-time that is acceptable for the user.
+//
+FunctionPass *createBoundsCheckingPass(unsigned Penalty = 5);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 7f055d446171..3dce6fe37fd4 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -74,7 +74,10 @@ FunctionPass *createAggressiveDCEPass();
// if possible.
//
FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1,
- bool UseDomTree = true);
+ bool UseDomTree = true,
+ signed StructMemberThreshold = -1,
+ signed ArrayElementThreshold = -1,
+ signed ScalarLoadThreshold = -1);
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 2f9dc54541b9..8a939cc75ed3 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -202,10 +202,6 @@ void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds,
ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred);
-/// GetFirstDebugLocInBasicBlock - Return first valid DebugLoc entry in a
-/// given basic block.
-DebugLoc GetFirstDebugLocInBasicBlock(const BasicBlock *BB);
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 17cd58eb014e..a6e41f0a27a8 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -15,7 +15,7 @@
#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H
#define TRANSFORMS_UTILS_BUILDLIBCALLS_H
-#include "llvm/Support/IRBuilder.h"
+#include "llvm/IRBuilder.h"
namespace llvm {
class Value;
@@ -28,41 +28,52 @@ namespace llvm {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, and the
/// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD);
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
+
+ /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
+ /// specified pointer. Ptr is required to be some pointer type, MaxLen must
+ /// be of size_t type, and the return value has 'intptr_t' type.
+ Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// EmitStrChr - Emit a call to the strchr function to the builder, for the
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD);
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD);
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const TargetData *TD, StringRef Name = "strcpy");
+ const TargetData *TD, const TargetLibraryInfo *TLI,
+ StringRef Name = "strcpy");
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
- const TargetData *TD, StringRef Name = "strncpy");
+ const TargetData *TD, const TargetLibraryInfo *TLI,
+ StringRef Name = "strncpy");
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const TargetData *TD);
+ IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
- const TargetData *TD);
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// EmitMemCmp - Emit a call to the memcmp function.
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD);
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
@@ -74,26 +85,28 @@ namespace llvm {
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD);
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
- void EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD);
+ Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an i32, and File is a pointer to FILE.
- void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const TargetData *TD);
+ Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
- void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD,
- const TargetLibraryInfo *TLI);
+ Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD,
+ const TargetLibraryInfo *TLI);
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
- void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
+ const TargetData *TD, const TargetLibraryInfo *TLI);
/// SimplifyFortifiedLibCalls - Helper class for folding checked library
/// calls (e.g. __strcpy_chk) into their unchecked counterparts.
@@ -105,7 +118,7 @@ namespace llvm {
bool isString) const = 0;
public:
virtual ~SimplifyFortifiedLibCalls();
- bool fold(CallInst *CI, const TargetData *TD);
+ bool fold(CallInst *CI, const TargetData *TD, const TargetLibraryInfo *TLI);
};
}
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
new file mode 100644
index 000000000000..1122678035b5
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -0,0 +1,127 @@
+//===-- Transform/Utils/CodeExtractor.h - Code extraction util --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A utility to support extracting code from one function into its own
+// stand-alone function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+#define LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace llvm {
+ class BasicBlock;
+ class DominatorTree;
+ class Function;
+ class Loop;
+ class Module;
+ class RegionNode;
+ class Type;
+ class Value;
+
+ /// \brief Utility class for extracting code into a new function.
+ ///
+ /// This utility provides a simple interface for extracting some sequence of
+ /// code into its own function, replacing it with a call to that function. It
+ /// also provides various methods to query about the nature and result of
+ /// such a transformation.
+ ///
+ /// The rough algorithm used is:
+ /// 1) Find both the inputs and outputs for the extracted region.
+ /// 2) Pass the inputs as arguments, remapping them within the extracted
+ /// function to arguments.
+ /// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas
+ /// as arguments, and inserting stores to the arguments for any scalars.
+ class CodeExtractor {
+ typedef SetVector<Value *> ValueSet;
+
+ // Various bits of state computed on construction.
+ DominatorTree *const DT;
+ const bool AggregateArgs;
+
+ // Bits of intermediate state computed at various phases of extraction.
+ SetVector<BasicBlock *> Blocks;
+ unsigned NumExitBlocks;
+ Type *RetTy;
+
+ public:
+ /// \brief Create a code extractor for a single basic block.
+ ///
+ /// In this formation, we don't require a dominator tree. The given basic
+ /// block is set up for extraction.
+ CodeExtractor(BasicBlock *BB, bool AggregateArgs = false);
+
+ /// \brief Create a code extractor for a sequence of blocks.
+ ///
+ /// Given a sequence of basic blocks where the first block in the sequence
+ /// dominates the rest, prepare a code extractor object for pulling this
+ /// sequence out into its new function. When a DominatorTree is also given,
+ /// extra checking and transformations are enabled.
+ CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = 0,
+ bool AggregateArgs = false);
+
+ /// \brief Create a code extractor for a loop body.
+ ///
+ /// Behaves just like the generic code sequence constructor, but uses the
+ /// block sequence of the loop.
+ CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs = false);
+
+ /// \brief Create a code extractor for a region node.
+ ///
+ /// Behaves just like the generic code sequence constructor, but uses the
+ /// block sequence of the region node passed in.
+ CodeExtractor(DominatorTree &DT, const RegionNode &RN,
+ bool AggregateArgs = false);
+
+ /// \brief Perform the extraction, returning the new function.
+ ///
+ /// Returns zero when called on a CodeExtractor instance where isEligible
+ /// returns false.
+ Function *extractCodeRegion();
+
+ /// \brief Test whether this code extractor is eligible.
+ ///
+ /// Based on the blocks used when constructing the code extractor,
+ /// determine whether it is eligible for extraction.
+ bool isEligible() const { return !Blocks.empty(); }
+
+ /// \brief Compute the set of input values and output values for the code.
+ ///
+ /// These can be used either when performing the extraction or to evaluate
+ /// the expected size of a call to the extracted function. Note that this
+ /// work cannot be cached between the two as once we decide to extract
+ /// a code sequence, that sequence is modified, including changing these
+ /// sets, before extraction occurs. These modifications won't have any
+ /// significant impact on the cost however.
+ void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs) const;
+
+ private:
+ void severSplitPHINodes(BasicBlock *&Header);
+ void splitReturnBlocks();
+
+ Function *constructFunction(const ValueSet &inputs,
+ const ValueSet &outputs,
+ BasicBlock *header,
+ BasicBlock *newRootNode, BasicBlock *newHeader,
+ Function *oldFunction, Module *M);
+
+ void moveCodeToFunction(Function *newFunction);
+
+ void emitCallAndSwitchStatement(Function *newFunction,
+ BasicBlock *newHeader,
+ ValueSet &inputs,
+ ValueSet &outputs);
+
+ };
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/FunctionUtils.h b/include/llvm/Transforms/Utils/FunctionUtils.h
deleted file mode 100644
index 8d71e43aa921..000000000000
--- a/include/llvm/Transforms/Utils/FunctionUtils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- Transform/Utils/FunctionUtils.h - Function Utils --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This family of transformations manipulate LLVM functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_FUNCTION_H
-#define LLVM_TRANSFORMS_UTILS_FUNCTION_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include <vector>
-
-namespace llvm {
- class BasicBlock;
- class DominatorTree;
- class Function;
- class Loop;
-
- /// ExtractCodeRegion - Rip out a sequence of basic blocks into a new
- /// function.
- ///
- Function* ExtractCodeRegion(DominatorTree& DT,
- ArrayRef<BasicBlock*> code,
- bool AggregateArgs = false);
-
- /// ExtractLoop - Rip out a natural loop into a new function.
- ///
- Function* ExtractLoop(DominatorTree& DT, Loop *L,
- bool AggregateArgs = false);
-
- /// ExtractBasicBlock - Rip out a basic block (and the associated landing pad)
- /// into a new function.
- ///
- Function* ExtractBasicBlock(ArrayRef<BasicBlock*> BBs,
- bool AggregateArgs = false);
-}
-
-#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 7f99dbcf895a..495eab73289e 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -15,6 +15,11 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+#include "llvm/IRBuilder.h"
+#include "llvm/Operator.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Target/TargetData.h"
+
namespace llvm {
class User;
@@ -160,6 +165,65 @@ static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
return getOrEnforceKnownAlignment(V, 0, TD);
}
+/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
+/// code necessary to compute the offset from the base pointer (without adding
+/// in the base pointer). Return the result as a signed integer of intptr size.
+/// When NoAssumptions is true, no assumptions about index computation not
+/// overflowing is made.
+template<typename IRBuilderTy>
+Value *EmitGEPOffset(IRBuilderTy *Builder, const TargetData &TD, User *GEP,
+ bool NoAssumptions = false) {
+ gep_type_iterator GTI = gep_type_begin(GEP);
+ Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
+ Value *Result = Constant::getNullValue(IntPtrTy);
+
+ // If the GEP is inbounds, we know that none of the addressing operations will
+ // overflow in an unsigned sense.
+ bool isInBounds = cast<GEPOperator>(GEP)->isInBounds() && !NoAssumptions;
+
+ // Build a mask for high order bits.
+ unsigned IntPtrWidth = TD.getPointerSizeInBits();
+ uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);
+
+ for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
+ ++i, ++GTI) {
+ Value *Op = *i;
+ uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
+ if (ConstantInt *OpC = dyn_cast<ConstantInt>(Op)) {
+ if (OpC->isZero()) continue;
+
+ // Handle a struct index, which adds its field offset to the pointer.
+ if (StructType *STy = dyn_cast<StructType>(*GTI)) {
+ Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
+
+ if (Size)
+ Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
+ GEP->getName()+".offs");
+ continue;
+ }
+
+ Constant *Scale = ConstantInt::get(IntPtrTy, Size);
+ Constant *OC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
+ Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
+ // Emit an add instruction.
+ Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
+ continue;
+ }
+ // Convert to correct type.
+ if (Op->getType() != IntPtrTy)
+ Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
+ if (Size != 1) {
+ // We'll let instcombine(mul) convert this to a shl if possible.
+ Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
+ GEP->getName()+".idx", isInBounds /*NUW*/);
+ }
+
+ // Emit an add instruction.
+ Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
+ }
+ return Result;
+}
+
///===---------------------------------------------------------------------===//
/// Dbg Intrinsic utilities
///
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 98d51a29ad71..0bb6ec69bbd5 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -21,7 +21,6 @@ namespace llvm {
class AllocaInst;
class DominatorTree;
-class DominanceFrontier;
class AliasSetTracker;
/// isAllocaPromotable - Return true if this alloca is legal for promotion.
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 652916c26c22..1e49a9c01e6b 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -28,6 +28,9 @@ struct VectorizeConfig {
/// @brief The size of the native vector registers.
unsigned VectorBits;
+ /// @brief Vectorize boolean values.
+ bool VectorizeBools;
+
/// @brief Vectorize integer values.
bool VectorizeInts;
@@ -49,6 +52,9 @@ struct VectorizeConfig {
/// @brief Vectorize select instructions.
bool VectorizeSelect;
+ /// @brief Vectorize comparison instructions.
+ bool VectorizeCmp;
+
/// @brief Vectorize getelementptr instructions.
bool VectorizeGEP;
@@ -80,6 +86,9 @@ struct VectorizeConfig {
/// @brief The maximum number of pairing iterations.
unsigned MaxIter;
+ /// @brief Don't try to form odd-length vectors.
+ bool Pow2LenOnly;
+
/// @brief Don't boost the chain-depth contribution of loads and stores.
bool NoMemOpBoost;
diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/TypeBuilder.h
index c75606917c1c..0b5647973184 100644
--- a/include/llvm/Support/TypeBuilder.h
+++ b/include/llvm/TypeBuilder.h
@@ -1,4 +1,4 @@
-//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===//
+//===---- llvm/TypeBuilder.h - Builder for LLVM types -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_TYPEBUILDER_H
-#define LLVM_SUPPORT_TYPEBUILDER_H
+#ifndef LLVM_TYPEBUILDER_H
+#define LLVM_TYPEBUILDER_H
#include "llvm/DerivedTypes.h"
#include "llvm/LLVMContext.h"
diff --git a/include/llvm/TypeFinder.h b/include/llvm/TypeFinder.h
new file mode 100644
index 000000000000..5d807057a32d
--- /dev/null
+++ b/include/llvm/TypeFinder.h
@@ -0,0 +1,78 @@
+//===-- llvm/TypeFinder.h - Class for finding used struct types -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the TypeFinder class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TYPEFINDER_H
+#define LLVM_TYPEFINDER_H
+
+#include "llvm/ADT/DenseSet.h"
+#include <vector>
+
+namespace llvm {
+
+class MDNode;
+class Module;
+class StructType;
+class Type;
+class Value;
+
+/// TypeFinder - Walk over a module, identifying all of the types that are
+/// used by the module.
+class TypeFinder {
+ // To avoid walking constant expressions multiple times and other IR
+ // objects, we keep several helper maps.
+ DenseSet<const Value*> VisitedConstants;
+ DenseSet<Type*> VisitedTypes;
+
+ std::vector<StructType*> StructTypes;
+ bool OnlyNamed;
+
+public:
+ TypeFinder() : OnlyNamed(false) {}
+
+ void run(const Module &M, bool onlyNamed);
+ void clear();
+
+ typedef std::vector<StructType*>::iterator iterator;
+ typedef std::vector<StructType*>::const_iterator const_iterator;
+
+ iterator begin() { return StructTypes.begin(); }
+ iterator end() { return StructTypes.end(); }
+
+ const_iterator begin() const { return StructTypes.begin(); }
+ const_iterator end() const { return StructTypes.end(); }
+
+ bool empty() const { return StructTypes.empty(); }
+ size_t size() const { return StructTypes.size(); }
+ iterator erase(iterator I, iterator E) { return StructTypes.erase(I, E); }
+
+ StructType *&operator[](unsigned Idx) { return StructTypes[Idx]; }
+
+private:
+ /// incorporateType - This method adds the type to the list of used
+ /// structures if it's not in there already.
+ void incorporateType(Type *Ty);
+
+ /// incorporateValue - This method is used to walk operand lists finding types
+ /// hiding in constant expressions and other operands that won't be walked in
+ /// other ways. GlobalValues, basic blocks, instructions, and inst operands
+ /// are all explicitly enumerated.
+ void incorporateValue(const Value *V);
+
+ /// incorporateMDNode - This method is used to walk the operands of an MDNode
+ /// to find types hiding within.
+ void incorporateMDNode(const MDNode *V);
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/User.h b/include/llvm/User.h
index c52f32f425c4..5d5460cd6fff 100644
--- a/include/llvm/User.h
+++ b/include/llvm/User.h
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
//
-// This class defines the interface that one who 'use's a Value must implement.
+// This class defines the interface that one who uses a Value must implement.
// Each instance of the Value class keeps track of what User's have handles
// to it.
//
-// * Instructions are the largest class of User's.
+// * Instructions are the largest class of Users.
// * Constants may be users of other constants (think arrays and stuff)
//
//===----------------------------------------------------------------------===//