summaryrefslogtreecommitdiffstats
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/DenseMap.h5
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h2
-rw-r--r--include/llvm/ADT/SparseBitVector.h16
-rw-r--r--include/llvm/ADT/StringRef.h4
-rw-r--r--include/llvm/ADT/Twine.h15
-rw-r--r--include/llvm/ADT/ilist_node.h50
-rw-r--r--include/llvm/Analysis/DebugInfo.h178
-rw-r--r--include/llvm/Analysis/InlineCost.h3
-rw-r--r--include/llvm/Analysis/Lint.h3
-rw-r--r--include/llvm/Analysis/Passes.h3
-rw-r--r--include/llvm/CallingConv.h7
-rw-r--r--include/llvm/CodeGen/ELFRelocation.h51
-rw-r--r--include/llvm/CodeGen/FastISel.h50
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h12
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h32
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h1
-rw-r--r--include/llvm/CodeGen/LiveInterval.h4
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h6
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h30
-rw-r--r--include/llvm/CodeGen/MachineFunction.h18
-rw-r--r--include/llvm/CodeGen/MachineInstr.h53
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h38
-rw-r--r--include/llvm/CodeGen/MachineSSAUpdater.h18
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h52
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h10
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h5
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h30
-rw-r--r--include/llvm/CodeGen/ValueTypes.h39
-rw-r--r--include/llvm/CodeGen/ValueTypes.td15
-rw-r--r--include/llvm/Config/config.h.cmake3
-rw-r--r--include/llvm/Config/config.h.in3
-rw-r--r--include/llvm/Constants.h10
-rw-r--r--include/llvm/Intrinsics.td6
-rw-r--r--include/llvm/IntrinsicsX86.td4
-rw-r--r--include/llvm/LinkAllPasses.h2
-rw-r--r--include/llvm/MC/MCAsmInfo.h5
-rw-r--r--include/llvm/MC/MCAsmLayout.h84
-rw-r--r--include/llvm/MC/MCAssembler.h197
-rw-r--r--include/llvm/MC/MCContext.h29
-rw-r--r--include/llvm/MC/MCExpr.h5
-rw-r--r--include/llvm/MC/MCFixup.h43
-rw-r--r--include/llvm/MC/MCLabel.h56
-rw-r--r--include/llvm/MC/MCMachOSymbolFlags.h44
-rw-r--r--include/llvm/MC/MCObjectWriter.h8
-rw-r--r--include/llvm/MC/MCParser/AsmParser.h2
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h2
-rw-r--r--include/llvm/MC/MCSection.h41
-rw-r--r--include/llvm/MC/MCSectionCOFF.h115
-rw-r--r--include/llvm/MC/MCSectionELF.h7
-rw-r--r--include/llvm/MC/MCSectionMachO.h22
-rw-r--r--include/llvm/MC/MCStreamer.h40
-rw-r--r--include/llvm/MC/MCSymbol.h29
-rw-r--r--include/llvm/MC/MachObjectWriter.h4
-rw-r--r--include/llvm/PassManager.h7
-rw-r--r--include/llvm/Support/Compiler.h17
-rw-r--r--include/llvm/Support/DOTGraphTraits.h8
-rw-r--r--include/llvm/Support/GraphWriter.h21
-rw-r--r--include/llvm/Support/StandardPasses.h14
-rw-r--r--include/llvm/System/Signals.h4
-rw-r--r--include/llvm/Target/SubtargetFeature.h7
-rw-r--r--include/llvm/Target/Target.td54
-rw-r--r--include/llvm/Target/TargetAsmBackend.h27
-rw-r--r--include/llvm/Target/TargetInstrInfo.h15
-rw-r--r--include/llvm/Target/TargetLowering.h211
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h7
-rw-r--r--include/llvm/Target/TargetMachine.h32
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h42
-rw-r--r--include/llvm/Target/TargetRegistry.h46
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h69
-rw-r--r--include/llvm/Transforms/Scalar.h6
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h22
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdaterImpl.h469
72 files changed, 1820 insertions, 769 deletions
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 393473bd..5c99473 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -79,13 +79,14 @@ public:
typedef DenseMapIterator<KeyT, ValueT,
KeyInfoT, ValueInfoT, true> const_iterator;
inline iterator begin() {
- return iterator(Buckets, Buckets+NumBuckets);
+ // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
+ return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
}
inline iterator end() {
return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
}
inline const_iterator begin() const {
- return const_iterator(Buckets, Buckets+NumBuckets);
+ return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
}
inline const_iterator end() const {
return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index 5f89823..91a1429 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -191,7 +191,7 @@ public:
/// insert - Insert a new value into the union/find set, ignoring the request
/// if the value already exists.
iterator insert(const ElemTy &Data) {
- return TheMapping.insert(Data).first;
+ return TheMapping.insert(ECValue(Data)).first;
}
/// findLeader - Given a value in the set, return a member iterator for the
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 6c813ec..0862981 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -889,13 +889,17 @@ operator-(const SparseBitVector<ElementSize> &LHS,
// Dump a SparseBitVector to a stream
template <unsigned ElementSize>
void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
- out << "[ ";
-
- typename SparseBitVector<ElementSize>::iterator bi;
- for (bi = LHS.begin(); bi != LHS.end(); ++bi) {
- out << *bi << " ";
+ out << "[";
+
+ typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
+ be = LHS.end();
+ if (bi != be) {
+ out << *bi;
+ for (++bi; bi != be; ++bi) {
+ out << " " << *bi;
+ }
}
- out << " ]\n";
+ out << "]\n";
}
} // end namespace llvm
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index ab6358b..33756f6 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -128,6 +128,10 @@ namespace llvm {
/// compare_lower - Compare two strings, ignoring case.
int compare_lower(StringRef RHS) const;
+ /// compare_numeric - Compare two strings, treating sequences of digits as
+ /// numbers.
+ int compare_numeric(StringRef RHS) const;
+
/// \brief Determine the edit distance between this string and another
/// string.
///
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index 97e9df4..b519a3e 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -99,11 +99,12 @@ namespace llvm {
/// A pointer to a StringRef instance.
StringRefKind,
- /// A pointer to an unsigned int value, to render as an unsigned decimal
- /// integer.
+ /// An unsigned int value reinterpreted as a pointer, to render as an
+ /// unsigned decimal integer.
DecUIKind,
- /// A pointer to an int value, to render as a signed decimal integer.
+ /// An int value reinterpreted as a pointer, to render as a signed
+ /// decimal integer.
DecIKind,
/// A pointer to an unsigned long value, to render as an unsigned decimal
@@ -259,13 +260,13 @@ namespace llvm {
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
- explicit Twine(const unsigned int &Val)
- : LHS(&Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
+ explicit Twine(unsigned Val)
+ : LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as a signed decimal integer.
- explicit Twine(const int &Val)
- : LHS(&Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
+ explicit Twine(int Val)
+ : LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
index da25f95..f008003 100644
--- a/include/llvm/ADT/ilist_node.h
+++ b/include/llvm/ADT/ilist_node.h
@@ -49,6 +49,56 @@ class ilist_node : private ilist_half_node<NodeTy> {
void setNext(NodeTy *N) { Next = N; }
protected:
ilist_node() : Next(0) {}
+
+public:
+ /// @name Adjacent Node Accessors
+ /// @{
+
+ /// \brief Get the previous node, or 0 for the list head.
+ NodeTy *getPrevNode() {
+ NodeTy *Prev = this->getPrev();
+
+ // Check for sentinel.
+ if (!Prev->getNext())
+ return 0;
+
+ return Prev;
+ }
+
+ /// \brief Get the previous node, or 0 for the list head.
+ const NodeTy *getPrevNode() const {
+ const NodeTy *Prev = this->getPrev();
+
+ // Check for sentinel.
+ if (!Prev->getNext())
+ return 0;
+
+ return Prev;
+ }
+
+ /// \brief Get the next node, or 0 for the list tail.
+ NodeTy *getNextNode() {
+ NodeTy *Next = getNext();
+
+ // Check for sentinel.
+ if (!Next->getNext())
+ return 0;
+
+ return Next;
+ }
+
+ /// \brief Get the next node, or 0 for the list tail.
+ const NodeTy *getNextNode() const {
+ const NodeTy *Next = getNext();
+
+ // Check for sentinel.
+ if (!Next->getNext())
+ return 0;
+
+ return Next;
+ }
+
+ /// @}
};
} // End llvm namespace
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index 9b1379d..473b127 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -34,13 +34,14 @@ namespace llvm {
class Instruction;
class MDNode;
class LLVMContext;
+ class raw_ostream;
/// 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.
class DIDescriptor {
protected:
- MDNode *DbgNode;
+ const MDNode *DbgNode;
StringRef getStringField(unsigned Elt) const;
unsigned getUnsignedField(unsigned Elt) const {
@@ -51,18 +52,19 @@ namespace llvm {
template <typename DescTy>
DescTy getFieldAs(unsigned Elt) const {
- return DescTy(getDescriptorField(Elt).getNode());
+ return DescTy(getDescriptorField(Elt));
}
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
public:
explicit DIDescriptor() : DbgNode(0) {}
- explicit DIDescriptor(MDNode *N) : DbgNode(N) {}
+ explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
bool Verify() const { return DbgNode != 0; }
- MDNode *getNode() const { return DbgNode; }
+ operator MDNode *() const { return const_cast<MDNode*>(DbgNode); }
+ MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); }
unsigned getVersion() const {
return getUnsignedField(0) & LLVMDebugVersionMask;
@@ -72,10 +74,10 @@ namespace llvm {
return getUnsignedField(0) & ~LLVMDebugVersionMask;
}
- /// ValidDebugInfo - Return true if N represents valid debug info value.
- static bool ValidDebugInfo(MDNode *N, unsigned OptLevel);
+ /// print - print descriptor.
+ void print(raw_ostream &OS) const;
- /// dump - print descriptor.
+ /// dump - print descriptor to dbgs() with a newline.
void dump() const;
bool isDerivedType() const;
@@ -98,7 +100,7 @@ namespace llvm {
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
public:
- explicit DISubrange(MDNode *N = 0) : DIDescriptor(N) {}
+ explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
int64_t getLo() const { return (int64_t)getUInt64Field(1); }
int64_t getHi() const { return (int64_t)getUInt64Field(2); }
@@ -107,7 +109,7 @@ namespace llvm {
/// DIArray - This descriptor holds an array of descriptors.
class DIArray : public DIDescriptor {
public:
- explicit DIArray(MDNode *N = 0)
+ explicit DIArray(const MDNode *N = 0)
: DIDescriptor(N) {}
unsigned getNumElements() const;
@@ -119,7 +121,7 @@ namespace llvm {
/// DIScope - A base class for various scopes.
class DIScope : public DIDescriptor {
public:
- explicit DIScope(MDNode *N = 0) : DIDescriptor (N) {}
+ explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
virtual ~DIScope() {}
StringRef getFilename() const;
@@ -129,7 +131,7 @@ namespace llvm {
/// DICompileUnit - A wrapper for a compile unit.
class DICompileUnit : public DIScope {
public:
- explicit DICompileUnit(MDNode *N = 0) : DIScope(N) {}
+ explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
unsigned getLanguage() const { return getUnsignedField(2); }
StringRef getFilename() const { return getStringField(3); }
@@ -153,14 +155,17 @@ namespace llvm {
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
- /// dump - print compile unit.
+ /// 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 {
public:
- explicit DIFile(MDNode *N = 0) : DIScope(N) {
+ explicit DIFile(const MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isFile())
DbgNode = 0;
}
@@ -174,7 +179,7 @@ namespace llvm {
/// type/precision or a file/line pair for location info.
class DIEnumerator : public DIDescriptor {
public:
- explicit DIEnumerator(MDNode *N = 0) : DIDescriptor(N) {}
+ explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
StringRef getName() const { return getStringField(1); }
uint64_t getEnumValue() const { return getUInt64Field(2); }
@@ -199,14 +204,14 @@ namespace llvm {
protected:
// This ctor is used when the Tag has already been validated by a derived
// ctor.
- DIType(MDNode *N, bool, bool) : DIScope(N) {}
+ DIType(const MDNode *N, bool, bool) : DIScope(N) {}
public:
/// Verify - Verify that a type descriptor is well formed.
bool Verify() const;
public:
- explicit DIType(MDNode *N);
+ explicit DIType(const MDNode *N);
explicit DIType() {}
virtual ~DIType() {}
@@ -253,18 +258,25 @@ namespace llvm {
}
StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
- /// dump - print type.
+
+ /// 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 {
public:
- explicit DIBasicType(MDNode *N = 0) : DIType(N) {}
+ explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
unsigned getEncoding() const { return getUnsignedField(9); }
- /// dump - print basic type.
+ /// print - print basic type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print basic type to dbgs() with a newline.
void dump() const;
};
@@ -272,10 +284,10 @@ namespace llvm {
/// a typedef, a pointer or reference, etc.
class DIDerivedType : public DIType {
protected:
- explicit DIDerivedType(MDNode *N, bool, bool)
+ explicit DIDerivedType(const MDNode *N, bool, bool)
: DIType(N, true, true) {}
public:
- explicit DIDerivedType(MDNode *N = 0)
+ explicit DIDerivedType(const MDNode *N = 0)
: DIType(N, true, true) {}
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
@@ -283,7 +295,11 @@ namespace llvm {
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t getOriginalTypeSize() const;
- /// dump - print derived type.
+
+ /// print - print derived type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print derived type to dbgs() with a newline.
void dump() const;
/// replaceAllUsesWith - Replace all uses of debug info referenced by
@@ -297,7 +313,7 @@ namespace llvm {
/// FIXME: Why is this a DIDerivedType??
class DICompositeType : public DIDerivedType {
public:
- explicit DICompositeType(MDNode *N = 0)
+ explicit DICompositeType(const MDNode *N = 0)
: DIDerivedType(N, true, true) {
if (N && !isCompositeType())
DbgNode = 0;
@@ -312,46 +328,17 @@ namespace llvm {
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
- /// dump - print composite type.
- void dump() const;
- };
-
- /// DIGlobal - This is a common class for global variables and subprograms.
- class DIGlobal : public DIDescriptor {
- protected:
- explicit DIGlobal(MDNode *N) : DIDescriptor(N) {}
-
- public:
- virtual ~DIGlobal() {}
-
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- StringRef getName() const { return getStringField(3); }
- StringRef getDisplayName() const { return getStringField(4); }
- StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{
- if (getVersion() == llvm::LLVMDebugVersion7)
- return getFieldAs<DICompileUnit>(6);
-
- DIFile F = getFieldAs<DIFile>(6);
- return F.getCompileUnit();
- }
-
- unsigned getLineNumber() const { return getUnsignedField(7); }
- DIType getType() const { return getFieldAs<DIType>(8); }
+ /// print - print composite type.
+ void print(raw_ostream &OS) const;
- /// isLocalToUnit - Return true if this subprogram is local to the current
- /// compile unit, like 'static' in C.
- unsigned isLocalToUnit() const { return getUnsignedField(9); }
- unsigned isDefinition() const { return getUnsignedField(10); }
-
- /// dump - print global.
+ /// dump - print composite type to dbgs() with a newline.
void dump() const;
};
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
public:
- explicit DISubprogram(MDNode *N = 0) : DIScope(N) {}
+ explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
@@ -373,7 +360,7 @@ namespace llvm {
DICompositeType DCT(getFieldAs<DICompositeType>(8));
if (DCT.Verify()) {
DIArray A = DCT.getTypeArray();
- DIType T(A.getElement(0).getNode());
+ DIType T(A.getElement(0));
return T.getName();
}
DIType T(getFieldAs<DIType>(8));
@@ -413,7 +400,10 @@ namespace llvm {
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
- /// dump - print subprogram.
+ /// 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
@@ -422,16 +412,36 @@ namespace llvm {
};
/// DIGlobalVariable - This is a wrapper for a global variable.
- class DIGlobalVariable : public DIGlobal {
+ class DIGlobalVariable : public DIDescriptor {
public:
- explicit DIGlobalVariable(MDNode *N = 0) : DIGlobal(N) {}
+ explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
+ StringRef getDisplayName() const { return getStringField(4); }
+ StringRef getLinkageName() const { return getStringField(5); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(6);
+
+ DIFile F = getFieldAs<DIFile>(6);
+ return F.getCompileUnit();
+ }
+
+ unsigned getLineNumber() const { return getUnsignedField(7); }
+ DIType getType() const { return getFieldAs<DIType>(8); }
+ unsigned isLocalToUnit() const { return getUnsignedField(9); }
+ unsigned isDefinition() const { return getUnsignedField(10); }
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
/// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const;
- /// dump - print global variable.
+ /// print - print global variable.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print global variable to dbgs() with a newline.
void dump() const;
};
@@ -439,7 +449,7 @@ namespace llvm {
/// global etc).
class DIVariable : public DIDescriptor {
public:
- explicit DIVariable(MDNode *N = 0)
+ explicit DIVariable(const MDNode *N = 0)
: DIDescriptor(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
@@ -479,14 +489,17 @@ namespace llvm {
/// information for an inlined function arguments.
bool isInlinedFnArgument(const Function *CurFn);
- /// dump - print variable.
+ /// print - print variable.
+ void print(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 {
public:
- explicit DILexicalBlock(MDNode *N = 0) : DIScope(N) {}
+ explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getDirectory() const { return getContext().getDirectory(); }
StringRef getFilename() const { return getContext().getFilename(); }
@@ -497,7 +510,7 @@ namespace llvm {
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
public:
- explicit DINameSpace(MDNode *N = 0) : DIScope(N) {}
+ explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
StringRef getDirectory() const { return getContext().getDirectory(); }
@@ -510,13 +523,14 @@ namespace llvm {
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(4); }
+ bool Verify() const;
};
/// DILocation - This object holds location information. This object
/// is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
public:
- explicit DILocation(MDNode *N) : DIDescriptor(N) { }
+ explicit DILocation(const MDNode *N) : DIDescriptor(N) { }
unsigned getLineNumber() const { return getUnsignedField(0); }
unsigned getColumnNumber() const { return getUnsignedField(1); }
@@ -663,7 +677,7 @@ namespace llvm {
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F, unsigned LineNo,
- DIType Ty);
+ DIType Ty, bool AlwaysPreserve = false);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
@@ -715,7 +729,7 @@ namespace llvm {
std::string &Dir);
/// getDISubprogram - Find subprogram that is enclosing this scope.
- DISubprogram getDISubprogram(MDNode *Scope);
+ DISubprogram getDISubprogram(const MDNode *Scope);
/// getDICompositeType - Find underlying composite type.
DICompositeType getDICompositeType(DIType T);
@@ -755,20 +769,20 @@ namespace llvm {
bool addType(DIType DT);
public:
- typedef SmallVector<MDNode *, 8>::iterator iterator;
- iterator compile_unit_begin() { return CUs.begin(); }
- iterator compile_unit_end() { return CUs.end(); }
- iterator subprogram_begin() { return SPs.begin(); }
- iterator subprogram_end() { return SPs.end(); }
- iterator global_variable_begin() { return GVs.begin(); }
- iterator global_variable_end() { return GVs.end(); }
- iterator type_begin() { return TYs.begin(); }
- iterator type_end() { return TYs.end(); }
-
- unsigned compile_unit_count() { return CUs.size(); }
- unsigned global_variable_count() { return GVs.size(); }
- unsigned subprogram_count() { return SPs.size(); }
- unsigned type_count() { return TYs.size(); }
+ typedef SmallVector<MDNode *, 8>::const_iterator iterator;
+ iterator compile_unit_begin() const { return CUs.begin(); }
+ iterator compile_unit_end() const { return CUs.end(); }
+ iterator subprogram_begin() const { return SPs.begin(); }
+ iterator subprogram_end() const { return SPs.end(); }
+ iterator global_variable_begin() const { return GVs.begin(); }
+ iterator global_variable_end() const { return GVs.end(); }
+ iterator type_begin() const { return TYs.begin(); }
+ iterator type_end() const { return TYs.end(); }
+
+ unsigned compile_unit_count() const { return CUs.size(); }
+ unsigned global_variable_count() const { return GVs.size(); }
+ unsigned subprogram_count() const { return SPs.size(); }
+ unsigned type_count() const { return TYs.size(); }
private:
SmallVector<MDNode *, 8> CUs; // Compile Units
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index d51dd6c..cac7cfe 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -198,6 +198,9 @@ namespace llvm {
/// has been inlined. If Callee is NULL it means a dead call has been
/// eliminated.
void growCachedCostInfo(Function* Caller, Function* Callee);
+
+ /// clear - empty the cache of inline costs
+ void clear();
};
/// callIsSmall - If a call is likely to lower to a single target instruction,
diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h
index 2f01366..eb65d22 100644
--- a/include/llvm/Analysis/Lint.h
+++ b/include/llvm/Analysis/Lint.h
@@ -38,8 +38,7 @@ FunctionPass *createLintPass();
/// This should only be used for debugging, because it plays games with
/// PassManagers and stuff.
void lintModule(
- const Module &M, ///< The module to be checked
- std::string *ErrorInfo = 0 ///< Information about failures.
+ const Module &M ///< The module to be checked
);
// lintFunction - Check a function.
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 1a5cbb2..ce3f7a6 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -153,6 +153,9 @@ namespace llvm {
// print debug info intrinsics in human readable form
FunctionPass *createDbgInfoPrinterPass();
+
+ // Print module-level debug info metadata in human-readable form.
+ ModulePass *createModuleDebugInfoPrinterPass();
}
#endif
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h
index 624390d..b0481b9 100644
--- a/include/llvm/CallingConv.h
+++ b/include/llvm/CallingConv.h
@@ -74,7 +74,12 @@ namespace CallingConv {
ARM_AAPCS_VFP = 68,
/// MSP430_INTR - Calling convention used for MSP430 interrupt routines.
- MSP430_INTR = 69
+ MSP430_INTR = 69,
+
+ /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
+ /// others via stack. Callee is responsible for stack cleaning. MSVC uses
+ /// this by default for methods in its ABI.
+ X86_ThisCall = 70
};
} // End CallingConv namespace
diff --git a/include/llvm/CodeGen/ELFRelocation.h b/include/llvm/CodeGen/ELFRelocation.h
deleted file mode 100644
index e58b8df..0000000
--- a/include/llvm/CodeGen/ELFRelocation.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//=== ELFRelocation.h - ELF Relocation 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 defines the ELFRelocation class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_ELF_RELOCATION_H
-#define LLVM_CODEGEN_ELF_RELOCATION_H
-
-#include "llvm/System/DataTypes.h"
-
-namespace llvm {
-
- /// ELFRelocation - This class contains all the information necessary to
- /// to generate any 32-bit or 64-bit ELF relocation entry.
- class ELFRelocation {
- uint64_t r_offset; // offset in the section of the object this applies to
- uint32_t r_symidx; // symbol table index of the symbol to use
- uint32_t r_type; // machine specific relocation type
- int64_t r_add; // explicit relocation addend
- bool r_rela; // if true then the addend is part of the entry
- // otherwise the addend is at the location specified
- // by r_offset
- public:
-
- uint64_t getInfo(bool is64Bit = false) const {
- if (is64Bit)
- return ((uint64_t)r_symidx << 32) + ((uint64_t)r_type & 0xFFFFFFFFL);
- else
- return (r_symidx << 8) + (r_type & 0xFFL);
- }
-
- uint64_t getOffset() const { return r_offset; }
- uint64_t getAddress() const { return r_add; }
-
- ELFRelocation(uint64_t off, uint32_t sym, uint32_t type,
- bool rela = true, int64_t addend = 0) :
- r_offset(off), r_symidx(sym), r_type(type),
- r_add(addend), r_rela(rela) {}
- };
-
-} // end llvm namespace
-
-#endif // LLVM_CODEGEN_ELF_RELOCATION_H
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 5a2b0e7..005c7bc 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -60,6 +60,7 @@ protected:
const TargetData &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
+ bool IsBottomUp;
public:
/// startNewBlock - Set the current block to which generated machine
@@ -105,7 +106,7 @@ public:
/// getRegForGEPIndex - This is a wrapper around getRegForValue that also
/// takes care of truncating or sign-extending the given getelementptr
/// index value.
- unsigned getRegForGEPIndex(const Value *V);
+ std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
virtual ~FastISel();
@@ -141,7 +142,8 @@ protected:
///
virtual unsigned FastEmit_r(MVT VT,
MVT RetVT,
- unsigned Opcode, unsigned Op0);
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill);
/// FastEmit_rr - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and
@@ -150,7 +152,8 @@ protected:
virtual unsigned FastEmit_rr(MVT VT,
MVT RetVT,
unsigned Opcode,
- unsigned Op0, unsigned Op1);
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill);
/// FastEmit_ri - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and
@@ -159,7 +162,8 @@ protected:
virtual unsigned FastEmit_ri(MVT VT,
MVT RetVT,
unsigned Opcode,
- unsigned Op0, uint64_t Imm);
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm);
/// FastEmit_rf - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and
@@ -168,7 +172,8 @@ protected:
virtual unsigned FastEmit_rf(MVT VT,
MVT RetVT,
unsigned Opcode,
- unsigned Op0, const ConstantFP *FPImm);
+ unsigned Op0, bool Op0IsKill,
+ const ConstantFP *FPImm);
/// FastEmit_rri - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and
@@ -177,7 +182,9 @@ protected:
virtual unsigned FastEmit_rri(MVT VT,
MVT RetVT,
unsigned Opcode,
- unsigned Op0, unsigned Op1, uint64_t Imm);
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ uint64_t Imm);
/// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries
/// to emit an instruction with an immediate operand using FastEmit_ri.
@@ -185,8 +192,8 @@ protected:
/// FastEmit_rr instead.
unsigned FastEmit_ri_(MVT VT,
unsigned Opcode,
- unsigned Op0, uint64_t Imm,
- MVT ImmType);
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm, MVT ImmType);
/// FastEmit_rf_ - This method is a wrapper of FastEmit_rf. It first tries
/// to emit an instruction with an immediate operand using FastEmit_rf.
@@ -194,8 +201,8 @@ protected:
/// FastEmit_rr instead.
unsigned FastEmit_rf_(MVT VT,
unsigned Opcode,
- unsigned Op0, const ConstantFP *FPImm,
- MVT ImmType);
+ unsigned Op0, bool Op0IsKill,
+ const ConstantFP *FPImm, MVT ImmType);
/// FastEmit_i - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and
@@ -224,35 +231,40 @@ protected:
///
unsigned FastEmitInst_r(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
- unsigned Op0);
+ unsigned Op0, bool Op0IsKill);
/// FastEmitInst_rr - Emit a MachineInstr with two register operands
/// and a result register in the given register class.
///
unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
- unsigned Op0, unsigned Op1);
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill);
/// FastEmitInst_ri - Emit a MachineInstr with two register operands
/// and a result register in the given register class.
///
unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
- unsigned Op0, uint64_t Imm);
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm);
/// FastEmitInst_rf - Emit a MachineInstr with two register operands
/// and a result register in the given register class.
///
unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
- unsigned Op0, const ConstantFP *FPImm);
+ unsigned Op0, bool Op0IsKill,
+ const ConstantFP *FPImm);
/// FastEmitInst_rri - Emit a MachineInstr with two register operands,
/// an immediate, and a result register in the given register class.
///
unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
- unsigned Op0, unsigned Op1, uint64_t Imm);
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ uint64_t Imm);
/// FastEmitInst_i - Emit a MachineInstr with a single immediate
/// operand, and a result register in the given register class.
@@ -263,12 +275,13 @@ protected:
/// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
/// from a specified index of a superregister to a specified type.
unsigned FastEmitInst_extractsubreg(MVT RetVT,
- unsigned Op0, uint32_t Idx);
+ unsigned Op0, bool Op0IsKill,
+ uint32_t Idx);
/// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op
/// with all but the least significant bit set to zero.
unsigned FastEmitZExtFromI1(MVT VT,
- unsigned Op);
+ unsigned Op0, bool Op0IsKill);
/// FastEmitBranch - Emit an unconditional branch to the given block,
/// unless it is the immediate (fall-through) successor, and update
@@ -316,6 +329,9 @@ private:
/// called when the value isn't already available in a register and must
/// be materialized with new instructions.
unsigned materializeRegForValue(const Value *V, MVT VT);
+
+ /// hasTrivialKill - Test whether the given value has exactly one use.
+ bool hasTrivialKill(const Value *V) const;
};
}
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index ba554d3..a5e9dd5 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -95,6 +95,18 @@ namespace ISD {
// execution to HANDLER. Many platform-related details also :)
EH_RETURN,
+ // 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.
+ 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
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index 7ac0418..13cebea 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -17,7 +17,6 @@
#define LATENCY_PRIORITY_QUEUE_H
#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/ADT/PriorityQueue.h"
namespace llvm {
class LatencyPriorityQueue;
@@ -41,10 +40,11 @@ namespace llvm {
std::vector<unsigned> NumNodesSolelyBlocking;
/// Queue - The queue.
- PriorityQueue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
+ std::vector<SUnit*> Queue;
+ latency_sort Picker;
-public:
- LatencyPriorityQueue() : Queue(latency_sort(this)) {
+ public:
+ LatencyPriorityQueue() : Picker(this) {
}
void initNodes(std::vector<SUnit> &sunits) {
@@ -73,31 +73,13 @@ public:
return NumNodesSolelyBlocking[NodeNum];
}
- unsigned size() const { return Queue.size(); }
-
bool empty() const { return Queue.empty(); }
- virtual void push(SUnit *U) {
- push_impl(U);
- }
- void push_impl(SUnit *U);
-
- void push_all(const std::vector<SUnit *> &Nodes) {
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
- push_impl(Nodes[i]);
- }
+ virtual void push(SUnit *U);
- SUnit *pop() {
- if (empty()) return NULL;
- SUnit *V = Queue.top();
- Queue.pop();
- return V;
- }
+ virtual SUnit *pop();
- void remove(SUnit *SU) {
- assert(!Queue.empty() && "Not in queue!");
- Queue.erase_one(SU);
- }
+ virtual void remove(SUnit *SU);
// ScheduledNode - As nodes are scheduled, we look to see if there are any
// successor nodes that have a single unscheduled predecessor. If so, that
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 0064776..b4c2f2f 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -46,6 +46,7 @@ namespace {
(void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createTDRRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Default);
+ (void) llvm::createHybridListDAGScheduler(NULL,llvm::CodeGenOpt::Default);
(void) llvm::createTDListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default);
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 70e79ce..637f52b 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -551,10 +551,6 @@ namespace llvm {
/// Also remove the value# from value# list.
void removeValNo(VNInfo *ValNo);
- /// scaleNumbering - Renumber VNI and ranges to provide gaps for new
- /// instructions.
- void scaleNumbering(unsigned factor);
-
/// getSize - Returns the sum of sizes of all the LiveRange's.
///
unsigned getSize() const;
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 351217c..32fa709 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -303,6 +303,12 @@ namespace llvm {
SlotIndex MIIdx,
MachineOperand& MO, unsigned MOIdx);
+ /// isPartialRedef - Return true if the specified def at the specific index
+ /// is partially re-defining the specified live interval. A common case of
+ /// this is a definition of the sub-register.
+ bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
+ LiveInterval &interval);
+
/// handleVirtualRegisterDef - update intervals for a virtual
/// register def
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index c7c5300..fe2c298 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -125,6 +125,10 @@ class MachineFrameInfo {
/// to builtin \@llvm.frameaddress.
bool FrameAddressTaken;
+ /// ReturnAddressTaken - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.returnaddress.
+ bool ReturnAddressTaken;
+
/// StackSize - The prolog/epilog code inserter calculates the final stack
/// offsets for all of the fixed size objects, updating the Objects list
/// above. It then updates StackSize to contain the number of bytes that need
@@ -152,8 +156,12 @@ class MachineFrameInfo {
///
unsigned MaxAlignment;
- /// HasCalls - Set to true if this function has any function calls. This is
- /// only valid during and after prolog/epilog code insertion.
+ /// AdjustsStack - Set to true if this function adjusts the stack -- e.g.,
+ /// when calling another function. This is only valid during and after
+ /// prolog/epilog code insertion.
+ bool AdjustsStack;
+
+ /// HasCalls - Set to true if this function has any function calls.
bool HasCalls;
/// StackProtectorIdx - The frame index for the stack protector.
@@ -189,6 +197,8 @@ public:
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
HasVarSizedObjects = false;
FrameAddressTaken = false;
+ ReturnAddressTaken = false;
+ AdjustsStack = false;
HasCalls = false;
StackProtectorIdx = -1;
MaxCallFrameSize = 0;
@@ -218,6 +228,12 @@ public:
bool isFrameAddressTaken() const { return FrameAddressTaken; }
void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
+ /// isReturnAddressTaken - This method may be called any time after instruction
+ /// selection is complete to determine if there is a call to
+ /// \@llvm.returnaddress in this function.
+ bool isReturnAddressTaken() const { return ReturnAddressTaken; }
+ void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
+
/// getObjectIndexBegin - Return the minimum frame object index.
///
int getObjectIndexBegin() const { return -NumFixedObjects; }
@@ -313,9 +329,13 @@ public:
///
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
- /// hasCalls - Return true if the current function has no function calls.
- /// This is only valid during or after prolog/epilog code emission.
- ///
+ /// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
+ /// when calling another function. This is only valid during and after
+ /// prolog/epilog code insertion.
+ bool adjustsStack() const { return AdjustsStack; }
+ void setAdjustsStack(bool V) { AdjustsStack = V; }
+
+ /// hasCalls - Return true if the current function has any function calls.
bool hasCalls() const { return HasCalls; }
void setHasCalls(bool V) { HasCalls = V; }
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 595872a..409d13ee 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -114,9 +114,14 @@ class MachineFunction {
///
unsigned FunctionNumber;
- /// The alignment of the function.
+ /// Alignment - The alignment of the function.
unsigned Alignment;
+ /// CallsSetJmp - True if the function calls setjmp or sigsetjmp. This is used
+ /// to limit optimizations which cannot reason about the control flow of
+ /// setjmp.
+ bool CallsSetJmp;
+
MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
void operator=(const MachineFunction&); // DO NOT IMPLEMENT
public:
@@ -181,6 +186,17 @@ public:
void EnsureAlignment(unsigned A) {
if (Alignment < A) Alignment = A;
}
+
+ /// callsSetJmp - Returns true if the function calls setjmp or sigsetjmp.
+ bool callsSetJmp() const {
+ return CallsSetJmp;
+ }
+
+ /// setCallsSetJmp - Set a flag that indicates if there's a call to setjmp or
+ /// sigsetjmp.
+ void setCallsSetJmp(bool B) {
+ CallsSetJmp = B;
+ }
/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index c4adca1..cf691bb 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -28,6 +28,7 @@
namespace llvm {
+template <typename T> class SmallVectorImpl;
class AliasAnalysis;
class TargetInstrDesc;
class TargetInstrInfo;
@@ -223,14 +224,33 @@ public:
bool isSubregToReg() const {
return getOpcode() == TargetOpcode::SUBREG_TO_REG;
}
+ bool isRegSequence() const {
+ return getOpcode() == TargetOpcode::REG_SEQUENCE;
+ }
/// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there
/// is a read of a super-register.
+ /// This does not count partial redefines of virtual registers as reads:
+ /// %reg1024:6 = OP.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const {
return findRegisterUseOperandIdx(Reg, false, TRI) != -1;
}
+ /// readsVirtualRegister - Return true if the MachineInstr reads the specified
+ /// virtual register. Take into account that a partial define is a
+ /// read-modify-write operation.
+ bool readsVirtualRegister(unsigned Reg) const {
+ return readsWritesVirtualRegister(Reg).first;
+ }
+
+ /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
+ /// indicating if this instruction reads or writes Reg. This also considers
+ /// partial defines.
+ /// If Ops is not null, all operand indices for Reg are added.
+ std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg,
+ SmallVectorImpl<unsigned> *Ops = 0) const;
+
/// killsRegister - Return true if the MachineInstr kills the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there is
/// a kill of a super-register.
@@ -238,12 +258,19 @@ public:
return findRegisterUseOperandIdx(Reg, true, TRI) != -1;
}
- /// modifiesRegister - Return true if the MachineInstr modifies the
+ /// definesRegister - Return true if the MachineInstr fully defines the
/// specified register. If TargetRegisterInfo is passed, then it also checks
/// if there is a def of a super-register.
- bool modifiesRegister(unsigned Reg,
- const TargetRegisterInfo *TRI = NULL) const {
- return findRegisterDefOperandIdx(Reg, false, TRI) != -1;
+ /// NOTE: It's ignoring subreg indices on virtual registers.
+ bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const {
+ return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1;
+ }
+
+ /// modifiesRegister - Return true if the MachineInstr modifies (fully define
+ /// or partially define) the specified register.
+ /// NOTE: It's ignoring subreg indices on virtual registers.
+ bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const {
+ return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1;
}
/// registerDefIsDead - Returns true if the register is dead in this machine
@@ -251,7 +278,7 @@ public:
/// if there is a dead def of a super-register.
bool registerDefIsDead(unsigned Reg,
const TargetRegisterInfo *TRI = NULL) const {
- return findRegisterDefOperandIdx(Reg, true, TRI) != -1;
+ return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1;
}
/// findRegisterUseOperandIdx() - Returns the operand index that is a use of
@@ -270,16 +297,18 @@ public:
/// findRegisterDefOperandIdx() - Returns the operand index that is a def of
/// the specified register or -1 if it is not found. If isDead is true, defs
- /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
- /// also checks if there is a def of a super-register.
- int findRegisterDefOperandIdx(unsigned Reg, bool isDead = false,
+ /// that are not dead are skipped. If Overlap is true, then it also looks for
+ /// defs that merely overlap the specified register. If TargetRegisterInfo is
+ /// non-null, then it also checks if there is a def of a super-register.
+ int findRegisterDefOperandIdx(unsigned Reg,
+ bool isDead = false, bool Overlap = false,
const TargetRegisterInfo *TRI = NULL) const;
/// findRegisterDefOperand - Wrapper for findRegisterDefOperandIdx, it returns
/// a pointer to the MachineOperand rather than an index.
MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false,
const TargetRegisterInfo *TRI = NULL) {
- int Idx = findRegisterDefOperandIdx(Reg, isDead, TRI);
+ int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI);
return (Idx == -1) ? NULL : &getOperand(Idx);
}
@@ -299,6 +328,10 @@ public:
/// reference if DefOpIdx is not null.
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const;
+ /// clearKillInfo - Clears kill flags on all operands.
+ ///
+ void clearKillInfo();
+
/// copyKillDeadInfo - Copies kill / dead operand properties from MI.
///
void copyKillDeadInfo(const MachineInstr *MI);
@@ -324,7 +357,7 @@ public:
/// addRegisterDefined - We have determined MI defines a register. Make sure
/// there is an operand defining Reg.
void addRegisterDefined(unsigned IncomingReg,
- const TargetRegisterInfo *RegInfo);
+ const TargetRegisterInfo *RegInfo = 0);
/// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index b377dec..fa14fdc 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -93,6 +93,20 @@ public:
/// specified register (it may be live-in).
bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
+ /// reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses
+ /// of the specified register, skipping those marked as Debug.
+ typedef defusechain_iterator<true,true,true> reg_nodbg_iterator;
+ reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const {
+ return reg_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_nodbg_iterator reg_nodbg_end() { return reg_nodbg_iterator(0); }
+
+ /// reg_nodbg_empty - Return true if the only instructions using or defining
+ /// Reg are Debug instructions.
+ bool reg_nodbg_empty(unsigned RegNo) const {
+ return reg_nodbg_begin(RegNo) == reg_nodbg_end();
+ }
+
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
typedef defusechain_iterator<false,true,false> def_iterator;
def_iterator def_begin(unsigned RegNo) const {
@@ -162,6 +176,12 @@ public:
/// 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;
+
+ /// 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
+ /// preserve conservative kill flag information.
+ void clearKillFlags(unsigned Reg) const;
#ifndef NDEBUG
void dumpUses(unsigned RegNo) const;
@@ -196,7 +216,8 @@ public:
/// getRegClassVirtRegs - Return the list of virtual registers of the given
/// target register class.
- std::vector<unsigned> &getRegClassVirtRegs(const TargetRegisterClass *RC) {
+ const std::vector<unsigned> &
+ getRegClassVirtRegs(const TargetRegisterClass *RC) const {
return RegClass2VRegMap[RC->getID()];
}
@@ -229,11 +250,18 @@ public:
/// setPhysRegUsed - Mark the specified register used in this function.
/// This should only be called during and after register allocation.
void setPhysRegUsed(unsigned Reg) { UsedPhysRegs[Reg] = true; }
-
+
+ /// addPhysRegsUsed - Mark the specified registers used in this function.
+ /// This should only be called during and after register allocation.
+ void addPhysRegsUsed(const BitVector &Regs) { UsedPhysRegs |= Regs; }
+
/// setPhysRegUnused - Mark the specified register unused in this function.
/// This should only be called during and after register allocation.
void setPhysRegUnused(unsigned Reg) { UsedPhysRegs[Reg] = false; }
-
+
+ /// closePhysRegsUsed - Expand UsedPhysRegs to its transitive closure over
+ /// subregisters. That means that if R is used, so are all subregisters.
+ void closePhysRegsUsed(const TargetRegisterInfo&);
//===--------------------------------------------------------------------===//
// LiveIn/LiveOut Management
@@ -265,6 +293,10 @@ public:
/// corresponding live-in physical register.
unsigned getLiveInPhysReg(unsigned VReg) const;
+ /// getLiveInVirtReg - If PReg is a live-in physical register, return the
+ /// corresponding live-in physical register.
+ unsigned getLiveInVirtReg(unsigned PReg) const;
+
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
/// into the given entry block.
void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h
index 979ef01..cbb45a7 100644
--- a/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -23,6 +23,7 @@ namespace llvm {
class TargetInstrInfo;
class TargetRegisterClass;
template<typename T> class SmallVectorImpl;
+ template<typename T> class SSAUpdaterTraits;
class BumpPtrAllocator;
/// MachineSSAUpdater - This class updates SSA form for a set of virtual
@@ -30,9 +31,7 @@ namespace llvm {
/// or another unstructured transformation wants to rewrite a set of uses of one
/// vreg with uses of a set of vregs.
class MachineSSAUpdater {
-public:
- class BBInfo;
- typedef SmallVectorImpl<BBInfo*> BlockListTy;
+ friend class SSAUpdaterTraits<MachineSSAUpdater>;
private:
/// AvailableVals - This keeps track of which value to use on a per-block
@@ -40,11 +39,6 @@ private:
//typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
void *AV;
- /// BBMap - The GetValueAtEndOfBlock method maintains this mapping from
- /// basic blocks to BBInfo structures.
- /// typedef DenseMap<MachineBasicBlock*, BBInfo*> BBMapTy;
- void *BM;
-
/// VR - Current virtual register whose uses are being updated.
unsigned VR;
@@ -111,14 +105,6 @@ public:
private:
void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
- void BuildBlockList(MachineBasicBlock *BB, BlockListTy *BlockList,
- BumpPtrAllocator *Allocator);
- void FindDominators(BlockListTy *BlockList);
- void FindPHIPlacement(BlockListTy *BlockList);
- void FindAvailableVals(BlockListTy *BlockList);
- void FindExistingPHI(MachineBasicBlock *BB, BlockListTy *BlockList);
- bool CheckIfPHIMatches(MachineInstr *PHI);
- void RecordMatchingPHI(MachineInstr *PHI);
void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 7c025e3..076268b 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -16,6 +16,7 @@
#define LLVM_CODEGEN_SCHEDULEDAG_H
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/GraphTraits.h"
@@ -34,7 +35,6 @@ namespace llvm {
class SDNode;
class TargetInstrInfo;
class TargetInstrDesc;
- class TargetLowering;
class TargetMachine;
class TargetRegisterClass;
template<class Graph> class GraphWriter;
@@ -226,7 +226,6 @@ namespace llvm {
private:
SDNode *Node; // Representative node.
MachineInstr *Instr; // Alternatively, a MachineInstr.
- MachineInstr *DbgInstr; // A dbg_value referencing this.
public:
SUnit *OrigNode; // If not this, the node from which
// this node was cloned.
@@ -240,7 +239,7 @@ namespace llvm {
typedef SmallVector<SDep, 4>::iterator succ_iterator;
typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
-
+
unsigned NodeNum; // Entry # of node in the node vector.
unsigned NodeQueueId; // Queue id of node.
unsigned short Latency; // Node latency.
@@ -257,6 +256,9 @@ namespace llvm {
bool isScheduled : 1; // True once scheduled.
bool isScheduleHigh : 1; // True if preferable to schedule high.
bool isCloned : 1; // True if this node has been cloned.
+ Sched::Preference SchedulingPref; // Scheduling preference.
+
+ SmallVector<MachineInstr*, 4> DbgInstrList; // dbg_values referencing this.
private:
bool isDepthCurrent : 1; // True if Depth is current.
bool isHeightCurrent : 1; // True if Height is current.
@@ -269,35 +271,38 @@ namespace llvm {
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
/// an SDNode and any nodes flagged to it.
SUnit(SDNode *node, unsigned nodenum)
- : Node(node), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(nodenum),
+ : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum),
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
+ SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct an SUnit for post-regalloc scheduling to represent
/// a MachineInstr.
SUnit(MachineInstr *instr, unsigned nodenum)
- : Node(0), Instr(instr), DbgInstr(0), OrigNode(0), NodeNum(nodenum),
+ : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum),
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
+ SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct a placeholder SUnit.
SUnit()
- : Node(0), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(~0u),
+ : Node(0), Instr(0), OrigNode(0), NodeNum(~0u),
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
+ SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
@@ -329,20 +334,6 @@ namespace llvm {
return Instr;
}
- /// setDbgInstr - Assign the debug instruction for the SUnit.
- /// This may be used during post-regalloc scheduling.
- void setDbgInstr(MachineInstr *MI) {
- assert(!Node && "Setting debug MachineInstr of SUnit with SDNode!");
- DbgInstr = MI;
- }
-
- /// getDbgInstr - Return the debug MachineInstr for this SUnit.
- /// This may be used during post-regalloc scheduling.
- MachineInstr *getDbgInstr() const {
- assert(!Node && "Reading debug MachineInstr of SUnit with SDNode!");
- return DbgInstr;
- }
-
/// addPred - This adds the specified edge as a pred of the current node if
/// not already. It also adds the current node as a successor of the
/// specified node.
@@ -404,7 +395,7 @@ namespace llvm {
return true;
return false;
}
-
+
void dump(const ScheduleDAG *G) const;
void dumpAll(const ScheduleDAG *G) const;
void print(raw_ostream &O, const ScheduleDAG *G) const;
@@ -423,7 +414,9 @@ namespace llvm {
/// implementation to decide.
///
class SchedulingPriorityQueue {
+ unsigned CurCycle;
public:
+ SchedulingPriorityQueue() : CurCycle(0) {}
virtual ~SchedulingPriorityQueue() {}
virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
@@ -431,11 +424,15 @@ namespace llvm {
virtual void updateNode(const SUnit *SU) = 0;
virtual void releaseState() = 0;
- virtual unsigned size() const = 0;
virtual bool empty() const = 0;
virtual void push(SUnit *U) = 0;
- virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
+ void push_all(const std::vector<SUnit *> &Nodes) {
+ for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
+ E = Nodes.end(); I != E; ++I)
+ push(*I);
+ }
+
virtual SUnit *pop() = 0;
virtual void remove(SUnit *SU) = 0;
@@ -447,6 +444,14 @@ namespace llvm {
virtual void ScheduledNode(SUnit *) {}
virtual void UnscheduledNode(SUnit *) {}
+
+ void setCurCycle(unsigned Cycle) {
+ CurCycle = Cycle;
+ }
+
+ unsigned getCurCycle() const {
+ return CurCycle;
+ }
};
class ScheduleDAG {
@@ -456,7 +461,6 @@ namespace llvm {
const TargetMachine &TM; // Target processor
const TargetInstrInfo *TII; // Target instruction information
const TargetRegisterInfo *TRI; // Target processor register info
- const TargetLowering *TLI; // Target lowering info
MachineFunction &MF; // Machine function
MachineRegisterInfo &MRI; // Virtual/real register map
std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
index cf3274f..14c33e2 100644
--- a/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -73,11 +73,17 @@ ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS,
ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level OptLevel);
-/// createBURRListDAGScheduler - This creates a bottom up register usage
-/// reduction list scheduler that schedules in source code order when possible.
+/// createBURRListDAGScheduler - This creates a bottom up list scheduler that
+/// schedules nodes in source code order when possible.
ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level OptLevel);
+/// createHybridListDAGScheduler - This creates a bottom up hybrid register
+/// usage reduction list scheduler that make use of latency information to
+/// avoid stalls for long latency instructions.
+ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level);
+
/// createTDListDAGScheduler - This creates a top-down list scheduler with
/// a hazard recognizer.
ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS,
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index ae15230..97202bd 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -36,6 +36,7 @@ class MDNode;
class SDNodeOrdering;
class SDDbgValue;
class TargetLowering;
+class TargetSelectionDAGInfo;
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
private:
@@ -131,6 +132,7 @@ void checkForCycles(const SelectionDAG *DAG);
class SelectionDAG {
const TargetMachine &TM;
const TargetLowering &TLI;
+ const TargetSelectionDAGInfo &TSI;
MachineFunction *MF;
FunctionLoweringInfo &FLI;
LLVMContext *Context;
@@ -201,6 +203,7 @@ public:
MachineFunction &getMachineFunction() const { return *MF; }
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
+ const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
LLVMContext *getContext() const {return Context; }
@@ -334,6 +337,8 @@ public:
SDValue getTargetConstant(const ConstantInt &Val, EVT VT) {
return getConstant(Val, VT, true);
}
+ // The forms below that take a double should only be used for simple
+ // constants that can be exactly represented in VT. No checks are made.
SDValue getConstantFP(double Val, EVT VT, bool isTarget = false);
SDValue getConstantFP(const APFloat& Val, EVT VT, bool isTarget = false);
SDValue getConstantFP(const ConstantFP &CF, EVT VT, bool isTarget = false);
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 90905f5..3aaab88 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -84,6 +84,23 @@ public:
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+ /// TLSDataSection - Section for thread local data.
+ ///
+ const MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// TLSBSSSection - Section for thread local uninitialized data.
+ ///
+ const MCSection *TLSBSSSection; // Defaults to ".tbss".
+
+ /// TLSTLVSection - Section for thread local structure infomation.
+ /// 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;
@@ -161,13 +178,15 @@ public:
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
+ const MCSection *DrectveSection;
public:
- TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
- ~TargetLoweringObjectFileCOFF();
+ TargetLoweringObjectFileCOFF() {}
+ ~TargetLoweringObjectFileCOFF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ virtual const MCSection *getDrectveSection() const { return DrectveSection; }
+
virtual const MCSection *
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
@@ -175,11 +194,6 @@ public:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
-
- /// getCOFFSection - Return the MCSection for the specified COFF section.
- /// FIXME: Switch this to a semantic view eventually.
- const MCSection *getCOFFSection(StringRef Name, bool isDirective,
- SectionKind K) const;
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index a7aafc0..6e2a102 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -63,21 +63,22 @@ namespace llvm {
v1i64 = 24, // 1 x i64
v2i64 = 25, // 2 x i64
v4i64 = 26, // 4 x i64
+ v8i64 = 27, // 8 x i64
- v2f32 = 27, // 2 x f32
- v4f32 = 28, // 4 x f32
- v8f32 = 29, // 8 x f32
- v2f64 = 30, // 2 x f64
- v4f64 = 31, // 4 x f64
+ v2f32 = 28, // 2 x f32
+ v4f32 = 29, // 4 x f32
+ v8f32 = 30, // 8 x f32
+ v2f64 = 31, // 2 x f64
+ v4f64 = 32, // 4 x f64
FIRST_VECTOR_VALUETYPE = v2i8,
LAST_VECTOR_VALUETYPE = v4f64,
- Flag = 32, // This glues nodes together during pre-RA sched
+ Flag = 33, // This glues nodes together during pre-RA sched
- isVoid = 33, // This has no value
+ isVoid = 34, // This has no value
- LAST_VALUETYPE = 34, // This always remains at the end of the list.
+ LAST_VALUETYPE = 35, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// EVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -140,7 +141,7 @@ namespace llvm {
bool isInteger() const {
return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
- (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v4i64));
+ (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64));
}
/// isVector - Return true if this is a vector value type.
@@ -192,7 +193,8 @@ namespace llvm {
case v8i32: return i32;
case v1i64:
case v2i64:
- case v4i64: return i64;
+ case v4i64:
+ case v8i64: return i64;
case v2f32:
case v4f32:
case v8f32: return f32;
@@ -211,6 +213,7 @@ namespace llvm {
case v8i8 :
case v8i16:
case v8i32:
+ case v8i64:
case v8f32: return 8;
case v4i8:
case v4i16:
@@ -269,6 +272,7 @@ namespace llvm {
case v4i64:
case v8f32:
case v4f64: return 256;
+ case v8i64: return 512;
}
}
@@ -332,6 +336,7 @@ namespace llvm {
if (NumElements == 1) return MVT::v1i64;
if (NumElements == 2) return MVT::v2i64;
if (NumElements == 4) return MVT::v4i64;
+ if (NumElements == 8) return MVT::v8i64;
break;
case MVT::f32:
if (NumElements == 2) return MVT::v2f32;
@@ -468,10 +473,15 @@ namespace llvm {
/// is256BitVector - Return true if this is a 256-bit vector type.
inline bool is256BitVector() const {
- return isSimple() ?
- (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 ||
- V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64) :
- isExtended256BitVector();
+ return isSimple()
+ ? (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 ||
+ V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64)
+ : isExtended256BitVector();
+ }
+
+ /// is512BitVector - Return true if this is a 512-bit vector type.
+ inline bool is512BitVector() const {
+ return isSimple() ? (V == MVT::v8i64) : isExtended512BitVector();
}
/// isOverloaded - Return true if this is an overloaded type for TableGen.
@@ -668,6 +678,7 @@ namespace llvm {
bool isExtended64BitVector() const;
bool isExtended128BitVector() const;
bool isExtended256BitVector() const;
+ bool isExtended512BitVector() 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 c8bb789..8151c0b 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -47,15 +47,16 @@ def v8i32 : ValueType<256, 23>; // 8 x i32 vector value
def v1i64 : ValueType<64 , 24>; // 1 x i64 vector value
def v2i64 : ValueType<128, 25>; // 2 x i64 vector value
def v4i64 : ValueType<256, 26>; // 4 x f64 vector value
+def v8i64 : ValueType<512, 27>; // 4 x f64 vector value
-def v2f32 : ValueType<64, 27>; // 2 x f32 vector value
-def v4f32 : ValueType<128, 28>; // 4 x f32 vector value
-def v8f32 : ValueType<256, 29>; // 8 x f32 vector value
-def v2f64 : ValueType<128, 30>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 31>; // 4 x f64 vector value
+def v2f32 : ValueType<64, 28>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 29>; // 4 x f32 vector value
+def v8f32 : ValueType<256, 30>; // 8 x f32 vector value
+def v2f64 : ValueType<128, 31>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 32>; // 4 x f64 vector value
-def FlagVT : ValueType<0 , 32>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 33>; // Produces no value
+def FlagVT : ValueType<0 , 33>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 34>; // Produces no value
def MetadataVT: ValueType<0, 250>; // Metadata
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index adbcc11..e7594ba 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -312,6 +312,9 @@
/* Define to 1 if you have the `roundf' function. */
#undef HAVE_ROUNDF
+/* Define to 1 if you have the `round' function. */
+#cmakedefine HAVE_ROUND ${HAVE_ROUND}
+
/* Define to 1 if you have the `sbrk' function. */
#cmakedefine HAVE_SBRK ${HAVE_SBRK}
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index c2ab23e..99d2ab5 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -24,6 +24,9 @@
/* Define if threads enabled */
#undef ENABLE_THREADS
+/* Define if timestamp information (e.g., __DATE___) is allowed */
+#undef ENABLE_TIMESTAMPS
+
/* Define to 1 if you have the `argz_append' function. */
#undef HAVE_ARGZ_APPEND
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 1cebb20..9ca845e 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -691,9 +691,6 @@ public:
// ConstantExpr class, because they will attempt to fold the constant
// expression into something simpler if possible.
- /// Cast constant expr
- ///
-
/// getAlignOf constant expr - computes the alignment of a type in a target
/// independent way (Note: the return type is an i64).
static Constant *getAlignOf(const Type* Ty);
@@ -926,7 +923,11 @@ DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant)
/// UndefValue - 'undef' values are things that do not have specified contents.
/// These are used for a variety of purposes, including global variable
/// initializers and operands to instructions. 'undef' values can occur with
-/// any type.
+/// any first-class type.
+///
+/// Undef values aren't exactly constants; if they have multiple uses, they
+/// can appear to have different bit patterns at each use. See
+/// LangRef.html#undefvalues for details.
///
class UndefValue : public Constant {
friend struct ConstantCreator<UndefValue, Type, char>;
@@ -957,6 +958,7 @@ public:
return V->getValueID() == UndefValueVal;
}
};
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 8bbfd77..2b4df54 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -306,11 +306,13 @@ def int_eh_unwind_init: Intrinsic<[]>,
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
let Properties = [IntrNoMem] in {
- def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
- def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>;
}
+def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_setjmp">;
+def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_longjmp">;
//===---------------- Generic Variable Attribute Intrinsics----------------===//
//
diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td
index 3ca9cb4..cea4856 100644
--- a/include/llvm/IntrinsicsX86.td
+++ b/include/llvm/IntrinsicsX86.td
@@ -786,9 +786,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_aesni_aesdeclast : GCCBuiltin<"__builtin_ia32_aesdeclast128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;
- def int_x86_aesni_aeskeygenassist :
+ def int_x86_aesni_aeskeygenassist :
GCCBuiltin<"__builtin_ia32_aeskeygenassist128">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
[IntrNoMem]>;
}
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 1e2c37a..c2375ea 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -132,12 +132,14 @@ namespace {
(void) llvm::createPrintModulePass(0);
(void) llvm::createPrintFunctionPass("", 0);
(void) llvm::createDbgInfoPrinterPass();
+ (void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass();
(void) llvm::createSSIPass();
(void) llvm::createSSIEverythingPass();
(void) llvm::createGEPSplitterPass();
(void) llvm::createABCDPass();
(void) llvm::createLintPass();
+ (void) llvm::createSinkingPass();
(void)new llvm::IntervalPartition();
(void)new llvm::FindUsedTypes();
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index f57f642..8516de0 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -41,6 +41,10 @@ namespace llvm {
/// the macho-specific .zerofill directive for emitting BSS Symbols.
bool HasMachoZeroFillDirective; // Default is false.
+ /// HasMachoTBSSDirective - True if this is a MachO target that supports
+ /// the macho-specific .tbss directive for emitting thread local BSS Symbols
+ bool HasMachoTBSSDirective; // Default is false.
+
/// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should
/// emit a ".reference .constructors_used" or ".reference .destructors_used"
/// directive after the a static ctor/dtor list. This directive is only
@@ -303,6 +307,7 @@ namespace llvm {
// Accessors.
//
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+ bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
bool hasStaticCtorDtorReferenceInStaticMode() const {
return HasStaticCtorDtorReferenceInStaticMode;
}
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index ebf0520..b9565ba 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -10,6 +10,8 @@
#ifndef LLVM_MC_MCASMLAYOUT_H
#define LLVM_MC_MCASMLAYOUT_H
+#include "llvm/ADT/SmallVector.h"
+
namespace llvm {
class MCAssembler;
class MCFragment;
@@ -24,11 +26,30 @@ class MCSymbolData;
/// efficiently compute the exact addresses of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
+public:
+ typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
+ typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
+
private:
MCAssembler &Assembler;
+ /// List of sections in layout order.
+ llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+
+ /// The last fragment which was layed out, or 0 if nothing has been layed
+ /// out. Fragments are always layed out in order, so all fragments with a
+ /// lower ordinal will be up to date.
+ mutable MCFragment *LastValidFragment;
+
+ /// \brief Make sure that the layout for the given fragment is valid, lazily
+ /// computing it if necessary.
+ void EnsureValid(const MCFragment *F) const;
+
+ bool isSectionUpToDate(const MCSectionData *SD) const;
+ bool isFragmentUpToDate(const MCFragment *F) const;
+
public:
- MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {}
+ MCAsmLayout(MCAssembler &_Assembler);
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
@@ -38,6 +59,33 @@ public:
/// the delta from the old size.
void UpdateForSlide(MCFragment *F, int SlideAmount);
+ /// \brief Update the layout because a fragment has been replaced.
+ void FragmentReplaced(MCFragment *Src, MCFragment *Dst);
+
+ /// \brief Perform a full layout.
+ void LayoutFile();
+
+ /// \brief Perform layout for a single fragment, assuming that the previous
+ /// fragment has already been layed out correctly, and the parent section has
+ /// been initialized.
+ void LayoutFragment(MCFragment *Fragment);
+
+ /// \brief Performs initial layout for a single section, assuming that the
+ /// previous section (including its fragments) has already been layed out
+ /// correctly.
+ void LayoutSection(MCSectionData *SD);
+
+ /// @name Section Access (in layout order)
+ /// @{
+
+ llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() {
+ return SectionOrder;
+ }
+ const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const {
+ return SectionOrder;
+ }
+
+ /// @}
/// @name Fragment Layout Data
/// @{
@@ -45,15 +93,9 @@ public:
/// current layout.
uint64_t getFragmentEffectiveSize(const MCFragment *F) const;
- /// \brief Set the effective size of the given fragment.
- void setFragmentEffectiveSize(MCFragment *F, uint64_t Value);
-
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
- /// \brief Set the offset of the given fragment inside its containing section.
- void setFragmentOffset(MCFragment *F, uint64_t Value);
-
/// @}
/// @name Section Layout Data
/// @{
@@ -61,22 +103,6 @@ public:
/// \brief Get the computed address of the given section.
uint64_t getSectionAddress(const MCSectionData *SD) const;
- /// \brief Set the computed address of the given section.
- void setSectionAddress(MCSectionData *SD, uint64_t Value);
-
- /// \brief Get the data size of the given section, as emitted to the object
- /// file. This may include additional padding, or be 0 for virtual sections.
- uint64_t getSectionFileSize(const MCSectionData *SD) const;
-
- /// \brief Set the data size of the given section.
- void setSectionFileSize(MCSectionData *SD, uint64_t Value);
-
- /// \brief Get the actual data size of the given section.
- uint64_t getSectionSize(const MCSectionData *SD) const;
-
- /// \brief Set the actual data size of the given section.
- void setSectionSize(MCSectionData *SD, uint64_t Value);
-
/// @}
/// @name Utility Functions
/// @{
@@ -85,6 +111,18 @@ public:
/// layout.
uint64_t getFragmentAddress(const MCFragment *F) const;
+ /// \brief Get the address space size of the given section, as it effects
+ /// layout. This may differ from the size reported by \see getSectionSize() by
+ /// not including section tail padding.
+ uint64_t getSectionAddressSize(const MCSectionData *SD) const;
+
+ /// \brief Get the data size of the given section, as emitted to the object
+ /// file. This may include additional padding, or be 0 for virtual sections.
+ uint64_t getSectionFileSize(const MCSectionData *SD) const;
+
+ /// \brief Get the logical data size of the given section.
+ uint64_t getSectionSize(const MCSectionData *SD) const;
+
/// \brief Get the address of the given symbol, as computed in the current
/// layout.
uint64_t getSymbolAddress(const MCSymbolData *SD) const;
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index c1b60f0..d9963ec 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -32,30 +32,10 @@ class MCObjectWriter;
class MCSection;
class MCSectionData;
class MCSymbol;
+class MCSymbolData;
class MCValue;
class TargetAsmBackend;
-/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
-/// which needs to be rewritten. This region will either be rewritten by the
-/// assembler or cause a relocation entry to be generated.
-//
-// FIXME: This should probably just be merged with MCFixup.
-class MCAsmFixup {
-public:
- /// Offset - The offset inside the fragment which needs to be rewritten.
- uint64_t Offset;
-
- /// Value - The expression to eventually write into the fragment.
- const MCExpr *Value;
-
- /// Kind - The fixup kind.
- MCFixupKind Kind;
-
-public:
- MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
- : Offset(_Offset), Value(&_Value), Kind(_Kind) {}
-};
-
class MCFragment : public ilist_node<MCFragment> {
friend class MCAsmLayout;
@@ -68,8 +48,7 @@ public:
FT_Data,
FT_Fill,
FT_Inst,
- FT_Org,
- FT_ZeroFill
+ FT_Org
};
private:
@@ -78,6 +57,11 @@ private:
/// Parent - The data for the section this fragment is in.
MCSectionData *Parent;
+ /// Atom - The atom this fragment is in, as represented by it's defining
+ /// symbol. Atom's are only used by backends which set
+ /// \see MCAsmBackend::hasReliableSymbolDifference().
+ MCSymbolData *Atom;
+
/// @name Assembler Backend Data
/// @{
//
@@ -91,9 +75,9 @@ private:
/// initialized.
uint64_t EffectiveSize;
- /// Ordinal - The global index of this fragment. This is the index across all
- /// sections, not just the parent section.
- unsigned Ordinal;
+ /// LayoutOrder - The global layout order of this fragment. This is the index
+ /// across all fragments in the file, not just within the section.
+ unsigned LayoutOrder;
/// @}
@@ -103,30 +87,32 @@ protected:
public:
// Only for sentinel.
MCFragment();
- virtual ~MCFragment();
FragmentType getKind() const { return Kind; }
MCSectionData *getParent() const { return Parent; }
void setParent(MCSectionData *Value) { Parent = Value; }
- unsigned getOrdinal() const { return Ordinal; }
- void setOrdinal(unsigned Value) { Ordinal = Value; }
+ MCSymbolData *getAtom() const { return Atom; }
+ void setAtom(MCSymbolData *Value) { Atom = Value; }
+
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
static bool classof(const MCFragment *O) { return true; }
- virtual void dump();
+ void dump();
};
class MCDataFragment : public MCFragment {
SmallString<32> Contents;
/// Fixups - The list of fixups in this fragment.
- std::vector<MCAsmFixup> Fixups;
+ std::vector<MCFixup> Fixups;
public:
- typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
- typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
+ typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
+ typedef std::vector<MCFixup>::iterator fixup_iterator;
public:
MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
@@ -141,15 +127,15 @@ public:
/// @name Fixup Access
/// @{
- void addFixup(MCAsmFixup Fixup) {
+ void addFixup(MCFixup Fixup) {
// Enforce invariant that fixups are in offset order.
- assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) &&
+ assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) &&
"Fixups must be added in order!");
Fixups.push_back(Fixup);
}
- std::vector<MCAsmFixup> &getFixups() { return Fixups; }
- const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
+ std::vector<MCFixup> &getFixups() { return Fixups; }
+ const std::vector<MCFixup> &getFixups() const { return Fixups; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -165,8 +151,6 @@ public:
return F->getKind() == MCFragment::FT_Data;
}
static bool classof(const MCDataFragment *) { return true; }
-
- virtual void dump();
};
// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
@@ -182,11 +166,11 @@ class MCInstFragment : public MCFragment {
SmallString<8> Code;
/// Fixups - The list of fixups in this fragment.
- SmallVector<MCAsmFixup, 1> Fixups;
+ SmallVector<MCFixup, 1> Fixups;
public:
- typedef SmallVectorImpl<MCAsmFixup>::const_iterator const_fixup_iterator;
- typedef SmallVectorImpl<MCAsmFixup>::iterator fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
public:
MCInstFragment(MCInst _Inst, MCSectionData *SD = 0)
@@ -210,8 +194,8 @@ public:
/// @name Fixup Access
/// @{
- SmallVectorImpl<MCAsmFixup> &getFixups() { return Fixups; }
- const SmallVectorImpl<MCAsmFixup> &getFixups() const { return Fixups; }
+ SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -227,8 +211,6 @@ public:
return F->getKind() == MCFragment::FT_Inst;
}
static bool classof(const MCInstFragment *) { return true; }
-
- virtual void dump();
};
class MCAlignFragment : public MCFragment {
@@ -245,17 +227,24 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
- /// EmitNops - true when aligning code and optimal nops to be used for
- /// filling.
- bool EmitNops;
+ /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+ /// of using the provided value. The exact interpretation of this flag is
+ /// target dependent.
+ bool EmitNops : 1;
+
+ /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust
+ /// the address space size of a section and that it should not be included as
+ /// part of the section size. This flag can only be used on the last fragment
+ /// in a section.
+ bool OnlyAlignAddress : 1;
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, bool _EmitNops,
- MCSectionData *SD = 0)
+ unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {}
+ MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false),
+ OnlyAlignAddress(false) {}
/// @name Accessors
/// @{
@@ -268,7 +257,11 @@ public:
unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
- unsigned getEmitNops() const { return EmitNops; }
+ bool hasEmitNops() const { return EmitNops; }
+ void setEmitNops(bool Value) { EmitNops = Value; }
+
+ bool hasOnlyAlignAddress() const { return OnlyAlignAddress; }
+ void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; }
/// @}
@@ -276,25 +269,27 @@ public:
return F->getKind() == MCFragment::FT_Align;
}
static bool classof(const MCAlignFragment *) { return true; }
-
- virtual void dump();
};
class MCFillFragment : public MCFragment {
/// Value - Value to use for filling bytes.
int64_t Value;
- /// ValueSize - The size (in bytes) of \arg Value to use when filling.
+ /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
+ /// this is a virtual fill fragment.
unsigned ValueSize;
- /// Count - The number of copies of \arg Value to insert.
- uint64_t Count;
+ /// Size - The number of bytes to insert.
+ uint64_t Size;
public:
- MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count,
+ MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
MCSectionData *SD = 0)
: MCFragment(FT_Fill, SD),
- Value(_Value), ValueSize(_ValueSize), Count(_Count) {}
+ Value(_Value), ValueSize(_ValueSize), Size(_Size) {
+ assert((!ValueSize || (Size % ValueSize) == 0) &&
+ "Fill size must be a multiple of the value size!");
+ }
/// @name Accessors
/// @{
@@ -303,7 +298,7 @@ public:
unsigned getValueSize() const { return ValueSize; }
- uint64_t getCount() const { return Count; }
+ uint64_t getSize() const { return Size; }
/// @}
@@ -311,8 +306,6 @@ public:
return F->getKind() == MCFragment::FT_Fill;
}
static bool classof(const MCFillFragment *) { return true; }
-
- virtual void dump();
};
class MCOrgFragment : public MCFragment {
@@ -340,39 +333,6 @@ public:
return F->getKind() == MCFragment::FT_Org;
}
static bool classof(const MCOrgFragment *) { return true; }
-
- virtual void dump();
-};
-
-/// MCZeroFillFragment - Represent data which has a fixed size and alignment,
-/// but requires no physical space in the object file.
-class MCZeroFillFragment : public MCFragment {
- /// Size - The size of this fragment.
- uint64_t Size;
-
- /// Alignment - The alignment for this fragment.
- unsigned Alignment;
-
-public:
- MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0)
- : MCFragment(FT_ZeroFill, SD),
- Size(_Size), Alignment(_Alignment) {}
-
- /// @name Accessors
- /// @{
-
- uint64_t getSize() const { return Size; }
-
- unsigned getAlignment() const { return Alignment; }
-
- /// @}
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_ZeroFill;
- }
- static bool classof(const MCZeroFillFragment *) { return true; }
-
- virtual void dump();
};
// FIXME: Should this be a separate class, or just merged into MCSection? Since
@@ -400,6 +360,9 @@ private:
/// Ordinal - The section index in the assemblers section list.
unsigned Ordinal;
+ /// LayoutOrder - The index of this section in the layout order.
+ unsigned LayoutOrder;
+
/// Alignment - The maximum alignment seen in this section.
unsigned Alignment;
@@ -412,13 +375,6 @@ private:
/// initialized.
uint64_t Address;
- /// Size - The content size of this section. This is ~0 until initialized.
- uint64_t Size;
-
- /// FileSize - The size of this section in the object file. This is ~0 until
- /// initialized.
- uint64_t FileSize;
-
/// HasInstructions - Whether this section has had instructions emitted into
/// it.
unsigned HasInstructions : 1;
@@ -441,6 +397,9 @@ public:
unsigned getOrdinal() const { return Ordinal; }
void setOrdinal(unsigned Value) { Ordinal = Value; }
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
/// @name Fragment Access
/// @{
@@ -562,6 +521,11 @@ public:
/// setFlags - Set the (implementation defined) symbol flags.
void setFlags(uint32_t Value) { Flags = Value; }
+ /// modifyFlags - Modify the flags via a mask
+ void modifyFlags(uint32_t Value, uint32_t Mask) {
+ Flags = (Flags & ~Mask) | Value;
+ }
+
/// getIndex - Get the (implementation defined) index.
uint64_t getIndex() const { return Index; }
@@ -642,26 +606,23 @@ private:
/// \arg Value result is fixed, otherwise the value may change due to
/// relocation.
bool EvaluateFixup(const MCAsmLayout &Layout,
- const MCAsmFixup &Fixup, const MCFragment *DF,
+ const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const;
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
- bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF,
+ bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF,
const MCAsmLayout &Layout) const;
/// Check whether the given fragment needs relaxation.
bool FragmentNeedsRelaxation(const MCInstFragment *IF,
const MCAsmLayout &Layout) const;
- /// LayoutSection - Assign the section the given \arg StartAddress, and then
- /// assign offsets and sizes to the fragments in the section \arg SD, and
- /// update the section size.
- ///
- /// \return The address at the end of the section, for use in laying out the
- /// succeeding section.
- uint64_t LayoutSection(MCSectionData &SD, MCAsmLayout &Layout,
- uint64_t StartAddress);
+ /// Compute the effective fragment size assuming it is layed out at the given
+ /// \arg SectionAddress and \arg FragmentOffset.
+ uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F,
+ uint64_t SectionAddress,
+ uint64_t FragmentOffset) const;
/// LayoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
@@ -671,18 +632,8 @@ private:
void FinishLayout(MCAsmLayout &Layout);
public:
- /// Find the symbol which defines the atom containing given address, inside
- /// the given section, or null if there is no such symbol.
- //
- // FIXME-PERF: Eliminate this, it is very slow.
- const MCSymbolData *getAtomForAddress(const MCAsmLayout &Layout,
- const MCSectionData *Section,
- uint64_t Address) const;
-
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.
- //
- // FIXME-PERF: Eliminate this, it is very slow.
const MCSymbolData *getAtom(const MCAsmLayout &Layout,
const MCSymbolData *Symbol) const;
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 4434341..03b5fb0 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -20,6 +20,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSymbol;
+ class MCLabel;
class StringRef;
class Twine;
class MCSectionMachO;
@@ -43,6 +44,15 @@ namespace llvm {
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
/// symbol.
unsigned NextUniqueID;
+
+ /// Instances of directional local labels.
+ DenseMap<unsigned, MCLabel *> Instances;
+ /// NextInstance() creates the next instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned NextInstance(int64_t LocalLabelVal);
+ /// GetInstance() gets the current instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned GetInstance(int64_t LocalLabelVal);
/// Allocator - Allocator object used for creating machine code objects.
///
@@ -50,7 +60,7 @@ namespace llvm {
/// objects.
BumpPtrAllocator Allocator;
- void *MachOUniquingMap, *ELFUniquingMap;
+ void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
public:
explicit MCContext(const MCAsmInfo &MAI);
~MCContext();
@@ -64,6 +74,14 @@ namespace llvm {
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
+ /// CreateDirectionalLocalSymbol - Create the defintion of a directional
+ /// local symbol for numbered label (used for "1:" defintions).
+ MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
+
+ /// GetDirectionalLocalSymbol - Create and return a directional local
+ /// symbol for numbered label (used for "1b" or 1f" references).
+ MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf);
+
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
/// reference and return it.
@@ -97,6 +115,15 @@ namespace llvm {
const MCSection *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind,
bool IsExplicit = false);
+
+ const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
+ int Selection, SectionKind Kind);
+
+ const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind) {
+ return getCOFFSection (Section, Characteristics, 0, Kind);
+ }
+
/// @}
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index bd0684d..1f9b8f2 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -134,7 +134,10 @@ public:
VK_NTPOFF,
VK_PLT,
VK_TLSGD,
- VK_TPOFF
+ VK_TPOFF,
+ VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the asm file)
+ VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file)
+ VK_TLVP // Mach-O thread local variable relocation
};
private:
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index cd0dd19..eed4c34 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -10,26 +10,12 @@
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
+#include "llvm/System/DataTypes.h"
#include <cassert>
namespace llvm {
class MCExpr;
-// Private constants, do not use.
-//
-// This is currently laid out so that the MCFixup fields can be efficiently
-// accessed, while keeping the offset field large enough that the assembler
-// backend can reasonably use the MCFixup representation for an entire fragment
-// (splitting any overly large fragments).
-//
-// The division of bits between the kind and the opindex can be tweaked if we
-// end up needing more bits for target dependent kinds.
-enum {
- MCFIXUP_NUM_GENERIC_KINDS = 128,
- MCFIXUP_NUM_KIND_BITS = 16,
- MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_KIND_BITS)
-};
-
/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
enum MCFixupKind {
FK_Data_1 = 0, ///< A one-byte fixup.
@@ -37,12 +23,14 @@ enum MCFixupKind {
FK_Data_4, ///< A four-byte fixup.
FK_Data_8, ///< A eight-byte fixup.
- FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS,
+ FirstTargetFixupKind = 128,
- MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS)
+ // Limit range of target fixups, in case we want to pack more efficiently
+ // later.
+ MaxTargetFixupKind = (1 << 8)
};
-/// MCFixup - Encode information on a single operation to perform on an byte
+/// MCFixup - Encode information on a single operation to perform on a byte
/// sequence (e.g., an encoded instruction) which requires assemble- or run-
/// time patching.
///
@@ -57,36 +45,33 @@ enum MCFixupKind {
/// fixups become relocations in the object file (or errors, if the fixup cannot
/// be encoded on the target).
class MCFixup {
- static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS;
-
/// The value to put into the fixup location. The exact interpretation of the
- /// expression is target dependent, usually it will one of the operands to an
- /// instruction or an assembler directive.
+ /// expression is target dependent, usually it will be one of the operands to
+ /// an instruction or an assembler directive.
const MCExpr *Value;
/// The byte index of start of the relocation inside the encoded instruction.
- unsigned Offset : MCFIXUP_NUM_OFFSET_BITS;
+ uint32_t Offset;
/// The target dependent kind of fixup item this is. The kind is used to
/// determine how the operand value should be encoded into the instruction.
- unsigned Kind : MCFIXUP_NUM_KIND_BITS;
+ unsigned Kind;
public:
- static MCFixup Create(unsigned Offset, const MCExpr *Value,
+ static MCFixup Create(uint32_t Offset, const MCExpr *Value,
MCFixupKind Kind) {
+ assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
MCFixup FI;
FI.Value = Value;
FI.Offset = Offset;
FI.Kind = unsigned(Kind);
-
- assert(Offset == FI.getOffset() && "Offset out of range!");
- assert(Kind == FI.getKind() && "Kind out of range!");
return FI;
}
MCFixupKind getKind() const { return MCFixupKind(Kind); }
- unsigned getOffset() const { return Offset; }
+ uint32_t getOffset() const { return Offset; }
+ void setOffset(uint32_t Value) { Offset = Value; }
const MCExpr *getValue() const { return Value; }
diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h
new file mode 100644
index 0000000..727520d
--- /dev/null
+++ b/include/llvm/MC/MCLabel.h
@@ -0,0 +1,56 @@
+//===- MCLabel.h - Machine Code Directional Local Labels --------*- 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 MCLabel class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLABEL_H
+#define LLVM_MC_MCLABEL_H
+
+namespace llvm {
+ class MCContext;
+ class raw_ostream;
+
+ /// MCLabel - Instances of this class represent a label name in the MC file,
+ /// and MCLabel are created and unique'd by the MCContext class. MCLabel
+ /// should only be constructed for valid instances in the object file.
+ class MCLabel {
+ // Instance - the instance number of this Directional Local Label
+ unsigned Instance;
+
+ private: // MCContext creates and uniques these.
+ friend class MCContext;
+ MCLabel(unsigned instance)
+ : Instance(instance) {}
+
+ MCLabel(const MCLabel&); // DO NOT IMPLEMENT
+ void operator=(const MCLabel&); // DO NOT IMPLEMENT
+ public:
+ /// getInstance - Get the current instance of this Directional Local Label.
+ unsigned getInstance() const { return Instance; }
+
+ /// incInstance - Increment the current instance of this Directional Local
+ /// Label.
+ unsigned incInstance() { return ++Instance; }
+
+ /// print - Print the value to the stream \arg OS.
+ void print(raw_ostream &OS) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
+ Label.print(OS);
+ return OS;
+ }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h
new file mode 100644
index 0000000..c938c81
--- /dev/null
+++ b/include/llvm/MC/MCMachOSymbolFlags.h
@@ -0,0 +1,44 @@
+//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolFlags used for the MachO target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
+#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
+
+// These flags are mostly used in MCMachOStreamer.cpp but also needed in
+// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
+// the correct relocation information.
+
+namespace llvm {
+ /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
+ /// 16 bits of the implementation defined flags.
+ enum SymbolFlags { // See <mach-o/nlist.h>.
+ SF_DescFlagsMask = 0xFFFF,
+
+ // Reference type flags.
+ SF_ReferenceTypeMask = 0x0007,
+ SF_ReferenceTypeUndefinedNonLazy = 0x0000,
+ SF_ReferenceTypeUndefinedLazy = 0x0001,
+ SF_ReferenceTypeDefined = 0x0002,
+ SF_ReferenceTypePrivateDefined = 0x0003,
+ SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+ SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
+
+ // Other 'desc' flags.
+ SF_NoDeadStrip = 0x0020,
+ SF_WeakReference = 0x0040,
+ SF_WeakDefinition = 0x0080
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 522ee77..e900584 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -15,9 +15,9 @@
#include <cassert>
namespace llvm {
-class MCAsmFixup;
class MCAsmLayout;
class MCAssembler;
+class MCFixup;
class MCFragment;
class MCValue;
class raw_ostream;
@@ -72,13 +72,13 @@ public:
virtual void RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
- const MCAsmFixup &Fixup, MCValue Target,
+ const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
/// Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
- /// complete, fixups have been evaluate and applied, and relocations
+ /// complete, fixups have been evaluated and applied, and relocations
/// generated.
virtual void WriteObject(const MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
@@ -152,6 +152,8 @@ public:
}
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
+ "data size greater than fill size, unexpected large write will occur");
OS << Str;
if (ZeroFillSize)
WriteZeros(ZeroFillSize - Str.size());
diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h
index 7a78906..e929fd1 100644
--- a/include/llvm/MC/MCParser/AsmParser.h
+++ b/include/llvm/MC/MCParser/AsmParser.h
@@ -131,11 +131,13 @@ private:
/// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
/// accepts a single symbol (which should be a label or an external).
bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
+ bool ParseDirectiveELFType(); // ELF specific ".type"
bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill"
+ bool ParseDirectiveDarwinTBSS(); // Darwin specific ".tbss"
// Darwin specific ".subsections_via_symbols"
bool ParseDirectiveDarwinSubsectionsViaSymbols();
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 075b69b..bd1496f 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -47,7 +47,7 @@ public:
Pipe, PipePipe, Caret,
Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
Less, LessEqual, LessLess, LessGreater,
- Greater, GreaterEqual, GreaterGreater
+ Greater, GreaterEqual, GreaterGreater, At
};
TokenKind Kind;
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index e9c19fc..808767c 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -17,6 +17,7 @@
#include <string>
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Casting.h"
namespace llvm {
class MCContext;
@@ -27,15 +28,27 @@ namespace llvm {
/// section in the current translation unit. The MCContext class uniques and
/// creates these.
class MCSection {
+ public:
+ enum SectionVariant {
+ SV_COFF = 0,
+ SV_ELF,
+ SV_MachO,
+ SV_PIC16
+ };
+
+ private:
MCSection(const MCSection&); // DO NOT IMPLEMENT
void operator=(const MCSection&); // DO NOT IMPLEMENT
protected:
- MCSection(SectionKind K) : Kind(K) {}
+ MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
+ SectionVariant Variant;
SectionKind Kind;
public:
virtual ~MCSection();
SectionKind getKind() const { return Kind; }
+
+ SectionVariant getVariant() const { return Variant; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const = 0;
@@ -47,32 +60,8 @@ namespace llvm {
virtual bool isBaseAddressKnownZero() const {
return false;
}
- };
-
- class MCSectionCOFF : public MCSection {
- // The memory for this string is stored in the same MCContext as *this.
- StringRef Name;
-
- /// IsDirective - This is true if the section name is a directive, not
- /// something that should be printed with ".section".
- ///
- /// FIXME: This is a hack. Switch to a semantic view of the section instead
- /// of a syntactic one.
- bool IsDirective;
-
- MCSectionCOFF(StringRef name, bool isDirective, SectionKind K)
- : MCSection(K), Name(name), IsDirective(isDirective) {
- }
- public:
-
- static MCSectionCOFF *Create(StringRef Name, bool IsDirective,
- SectionKind K, MCContext &Ctx);
- StringRef getName() const { return Name; }
- bool isDirective() const { return IsDirective; }
-
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS) const;
+ static bool classof(const MCSection *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
new file mode 100644
index 0000000..938a388
--- /dev/null
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -0,0 +1,115 @@
+//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionCOFF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONCOFF_H
+#define LLVM_MC_MCSECTIONCOFF_H
+
+#include "llvm/MC/MCSection.h"
+
+namespace llvm {
+
+/// MCSectionCOFF - This represents a section on Windows
+ class MCSectionCOFF : public MCSection {
+ // The memory for this string is stored in the same MCContext as *this.
+ StringRef SectionName;
+
+ /// Characteristics - This is the Characteristics field of a section,
+ // drawn from the enums below.
+ unsigned Characteristics;
+
+ /// Selection - This is the Selection field for the section symbol, if
+ /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
+ int Selection;
+
+ private:
+ friend class MCContext;
+ MCSectionCOFF(StringRef Section, unsigned Characteristics,
+ int Selection, SectionKind K)
+ : MCSection(SV_COFF, K), SectionName(Section),
+ Characteristics(Characteristics), Selection (Selection) {
+ assert ((Characteristics & 0x00F00000) == 0 &&
+ "alignment must not be set upon section creation");
+ }
+ ~MCSectionCOFF();
+
+ public:
+ /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+ /// should be printed before the section name
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ //FIXME: all COFF enumerations/flags should be standardized into one place...
+ // Target/X86COFF.h doesn't seem right as COFF can be used for other targets,
+ // MC/WinCOFF.h maybe right as it isn't target or entity specific, and it is
+ // pretty low on the dependancy graph (is there any need to support non
+ // windows COFF?)
+ // here is good for section stuff, but others should go elsewhere
+
+ /// Valid section flags.
+ enum {
+ IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
+ IMAGE_SCN_CNT_CODE = 0x00000020,
+ IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
+ IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
+ IMAGE_SCN_LNK_OTHER = 0x00000100,
+ IMAGE_SCN_LNK_INFO = 0x00000200,
+ IMAGE_SCN_LNK_REMOVE = 0x00000800,
+ IMAGE_SCN_LNK_COMDAT = 0x00001000,
+ IMAGE_SCN_MEM_FARDATA = 0x00008000,
+ IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
+ IMAGE_SCN_MEM_16BIT = 0x00020000,
+ IMAGE_SCN_MEM_LOCKED = 0x00040000,
+ IMAGE_SCN_MEM_PRELOAD = 0x00080000,
+ /* these are handled elsewhere
+ IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
+ IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
+ IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
+ IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
+ IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
+ IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
+ IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
+ */
+ IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
+ IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
+ IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
+ IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
+ IMAGE_SCN_MEM_SHARED = 0x10000000,
+ IMAGE_SCN_MEM_EXECUTE = 0x20000000,
+ IMAGE_SCN_MEM_READ = 0x40000000,
+ IMAGE_SCN_MEM_WRITE = 0x80000000
+ };
+
+ enum {
+ IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
+ IMAGE_COMDAT_SELECT_ANY,
+ IMAGE_COMDAT_SELECT_SAME_SIZE,
+ IMAGE_COMDAT_SELECT_EXACT_MATCH,
+ IMAGE_COMDAT_SELECT_ASSOCIATIVE,
+ IMAGE_COMDAT_SELECT_LARGEST
+ };
+
+ StringRef getSectionName() const { return SectionName; }
+ unsigned getCharacteristics() const { return Characteristics; }
+ int getSelection () const { return Selection; }
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
+ raw_ostream &OS) const;
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_COFF;
+ }
+ static bool classof(const MCSectionCOFF *) { return true; }
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 7054668..5fe8171 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -40,7 +40,7 @@ private:
friend class MCContext;
MCSectionELF(StringRef Section, unsigned type, unsigned flags,
SectionKind K, bool isExplicit)
- : MCSection(K), SectionName(Section), Type(type), Flags(flags),
+ : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
IsExplicit(isExplicit) {}
~MCSectionELF();
public:
@@ -178,6 +178,11 @@ public:
virtual bool isBaseAddressKnownZero() const {
return (getFlags() & SHF_ALLOC) == 0;
}
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_ELF;
+ }
+ static bool classof(const MCSectionELF *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index f3bc8ed..2d9d133 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -87,8 +87,20 @@ public:
/// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
/// lazy loaded dylibs.
S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10U,
+ /// S_THREAD_LOCAL_REGULAR - Section with ....
+ S_THREAD_LOCAL_REGULAR = 0x11U,
+ /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
+ S_THREAD_LOCAL_ZEROFILL = 0x12U,
+ /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable structure
+ /// data.
+ S_THREAD_LOCAL_VARIABLES = 0x13U,
+ /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with ....
+ S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14U,
+ /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
+ /// variable initialization pointers to functions.
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U,
- LAST_KNOWN_SECTION_TYPE = S_LAZY_DYLIB_SYMBOL_POINTERS,
+ LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
// Valid section attributes.
@@ -136,6 +148,9 @@ public:
unsigned getStubSize() const { return Reserved2; }
unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
+ bool hasAttribute(unsigned Value) const {
+ return (TypeAndAttributes & Value) != 0;
+ }
/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
/// This is a string that can appear after a .section directive in a mach-o
@@ -150,6 +165,11 @@ public:
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_MachO;
+ }
+ static bool classof(const MCSectionMachO *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 4667c41..0783159 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -27,7 +27,7 @@ namespace llvm {
class MCSection;
class MCSymbol;
class StringRef;
-class TargetAsmBackend;
+ class TargetAsmBackend;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
@@ -138,7 +138,24 @@ class TargetAsmBackend;
/// @param DescValue - The value to set into the n_desc field.
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
-
+ /// BeginCOFFSymbolDef - Start emitting COFF symbol definition
+ ///
+ /// @param Symbol - The symbol to have its External & Type fields set.
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
+
+ /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
+ ///
+ /// @param StorageClass - The storage class the symbol should have.
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
+
+ /// EmitCOFFSymbolType - Emit the type of the symbol.
+ ///
+ /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
+ virtual void EmitCOFFSymbolType(int Type) = 0;
+
+ /// EndCOFFSymbolDef - Marks the end of the symbol definition.
+ virtual void EndCOFFSymbolDef() = 0;
+
/// EmitELFSize - Emit an ELF .size directive.
///
/// This corresponds to an assembler statement such as:
@@ -161,7 +178,7 @@ class TargetAsmBackend;
/// @param Size - The size of the common symbol.
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0;
- /// EmitZerofill - Emit a the zerofill section and an option symbol.
+ /// EmitZerofill - Emit the zerofill section and an optional symbol.
///
/// @param Section - The zerofill section to create and or to put the symbol
/// @param Symbol - The zerofill symbol to emit, if non-NULL.
@@ -171,6 +188,15 @@ class TargetAsmBackend;
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
unsigned Size = 0,unsigned ByteAlignment = 0) = 0;
+ /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
+ ///
+ /// @param Section - The thread local common section.
+ /// @param Symbol - The thread local common symbol to emit.
+ /// @param Size - The size of the symbol.
+ /// @param ByteAlignment - The alignment of the thread local common symbol
+ /// if non-zero. This must be a power of 2 on some targets.
+ virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0) = 0;
/// @}
/// @name Generating Data
/// @{
@@ -315,12 +341,18 @@ class TargetAsmBackend;
MCCodeEmitter *CE = 0,
bool ShowInst = false);
- /// createMachOStream - Create a machine code streamer which will generative
+ /// createMachOStreamer - Create a machine code streamer which will generative
/// Mach-O format object files.
MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll = false);
+ /// createLoggingStreamer - Create a machine code streamer which just logs the
+ /// API calls and then dispatches to another streamer.
+ ///
+ /// The new streamer takes ownership of the \arg Child.
+ MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index fb96506..1b432c2 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -52,10 +52,15 @@ namespace llvm {
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
+ /// IsUsedInExpr - True if this symbol has been used in an expression and
+ /// cannot be redefined.
+ unsigned IsUsedInExpr : 1;
+
private: // MCContext creates and uniques these.
friend class MCContext;
MCSymbol(StringRef name, bool isTemporary)
- : Name(name), Section(0), Value(0), IsTemporary(isTemporary) {}
+ : Name(name), Section(0), Value(0),
+ IsTemporary(isTemporary), IsUsedInExpr(false) {}
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
@@ -63,13 +68,15 @@ namespace llvm {
/// getName - Get the symbol name.
StringRef getName() const { return Name; }
- /// @name Symbol Type
+ /// @name Accessors
/// @{
/// isTemporary - Check if this is an assembler temporary symbol.
- bool isTemporary() const {
- return IsTemporary;
- }
+ bool isTemporary() const { return IsTemporary; }
+
+ /// isUsedInExpr - Check if this is an assembler temporary symbol.
+ bool isUsedInExpr() const { return IsUsedInExpr; }
+ void setUsedInExpr(bool Value) { IsUsedInExpr = Value; }
/// @}
/// @name Associated Sections
@@ -125,14 +132,14 @@ namespace llvm {
return Value != 0;
}
- /// getValue() - Get the value for variable symbols, or null if the symbol
- /// is not a variable.
- const MCExpr *getValue() const { return Value; }
-
- void setValue(const MCExpr *Value) {
- this->Value = Value;
+ /// getValue() - Get the value for variable symbols.
+ const MCExpr *getVariableValue() const {
+ assert(isVariable() && "Invalid accessor!");
+ return Value;
}
+ void setVariableValue(const MCExpr *Value);
+
/// @}
/// print - Print the value to the stream \arg OS.
diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h
index 844025d..9b1ff1d 100644
--- a/include/llvm/MC/MachObjectWriter.h
+++ b/include/llvm/MC/MachObjectWriter.h
@@ -15,9 +15,9 @@
#include <cassert>
namespace llvm {
-class MCAsmFixup;
class MCAssembler;
class MCFragment;
+class MCFixup;
class MCValue;
class raw_ostream;
@@ -33,7 +33,7 @@ public:
virtual void RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
- const MCAsmFixup &Fixup, MCValue Target,
+ const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h
index 4d91163..8de0f83 100644
--- a/include/llvm/PassManager.h
+++ b/include/llvm/PassManager.h
@@ -60,6 +60,9 @@ public:
bool run(Module &M);
private:
+ /// addImpl - Add a pass to the queue of passes to run, without
+ /// checking whether to add a printer pass.
+ void addImpl(Pass *P);
/// PassManagerImpl_New is the actual class. PassManager is just the
/// wraper to publish simple pass manager interface
@@ -96,6 +99,10 @@ public:
bool doFinalization();
private:
+ /// addImpl - Add a pass to the queue of passes to run, without
+ /// checking whether to add a printer pass.
+ void addImpl(Pass *P);
+
FunctionPassManagerImpl *FPM;
Module *M;
};
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 881a0fe..b2ce76d 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -15,12 +15,21 @@
#ifndef LLVM_SUPPORT_COMPILER_H
#define LLVM_SUPPORT_COMPILER_H
-// The VISIBILITY_HIDDEN macro, used for marking classes with the GCC-specific
-// visibility("hidden") attribute.
+/// 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
+/// functions, making them private to any shared library they are linked into.
+
+/// LLVM_GLOBAL_VISIBILITY - If a class marked with this attribute is linked
+/// into a shared library, then the class will be accessible from outside the
+/// the library. Can also be used to mark variables and functions, making them
+/// accessible from outside any shared library they are linked into.
#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
-#define VISIBILITY_HIDDEN __attribute__ ((visibility("hidden")))
+#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
+#define LLVM_GLOBAL_VISIBILITY __attribute__ ((visibility("default")))
#else
-#define VISIBILITY_HIDDEN
+#define LLVM_LIBRARY_VISIBILITY
+#define LLVM_GLOBAL_VISIBILITY
#endif
#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
index 54ced15..796c74a 100644
--- a/include/llvm/Support/DOTGraphTraits.h
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -36,7 +36,7 @@ protected:
}
public:
- DefaultDOTGraphTraits (bool simple=false) : IsSimple (simple) {}
+ explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {}
/// getGraphName - Return the label for the graph as a whole. Printed at the
/// top of the graph.
@@ -59,6 +59,12 @@ public:
return false;
}
+ /// isNodeHidden - If the function returns true, the given node is not
+ /// displayed in the graph.
+ static bool isNodeHidden(const void *Node) {
+ return false;
+ }
+
/// getNodeLabel - Given a node and a pointer to the top level graph, return
/// the label to print in the node.
template<typename GraphType>
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 13e6682..559f004 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -122,7 +122,20 @@ public:
// Loop over the graph, printing it out...
for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
I != E; ++I)
- writeNode(*I);
+ if (!isNodeHidden(*I))
+ writeNode(*I);
+ }
+
+ bool isNodeHidden(NodeType &Node) {
+ return isNodeHidden(&Node);
+ }
+
+ bool isNodeHidden(NodeType *const *Node) {
+ return isNodeHidden(*Node);
+ }
+
+ bool isNodeHidden(NodeType *Node) {
+ return DTraits.isNodeHidden(Node);
}
void writeNode(NodeType& Node) {
@@ -189,9 +202,11 @@ public:
child_iterator EI = GTraits::child_begin(Node);
child_iterator EE = GTraits::child_end(Node);
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
- writeEdge(Node, i, EI);
+ if (!DTraits.isNodeHidden(*EI))
+ writeEdge(Node, i, EI);
for (; EI != EE; ++EI)
- writeEdge(Node, 64, EI);
+ if (!DTraits.isNodeHidden(*EI))
+ writeEdge(Node, 64, EI);
}
void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h
index f233c18..b97ad29 100644
--- a/include/llvm/Support/StandardPasses.h
+++ b/include/llvm/Support/StandardPasses.h
@@ -31,7 +31,7 @@ namespace llvm {
///
/// \arg OptimizationLevel - The optimization level, corresponding to -O0,
/// -O1, etc.
- static inline void createStandardFunctionPasses(FunctionPassManager *PM,
+ static inline void createStandardFunctionPasses(PassManagerBase *PM,
unsigned OptimizationLevel);
/// createStandardModulePasses - Add the standard list of module passes to the
@@ -46,7 +46,7 @@ namespace llvm {
/// \arg HaveExceptions - Whether the module may have code using exceptions.
/// \arg InliningPass - The inlining pass to use, if any, or null. This will
/// always be added, even at -O0.a
- static inline void createStandardModulePasses(PassManager *PM,
+ static inline void createStandardModulePasses(PassManagerBase *PM,
unsigned OptimizationLevel,
bool OptimizeSize,
bool UnitAtATime,
@@ -61,14 +61,14 @@ namespace llvm {
/// Internalize - Run the internalize pass.
/// RunInliner - Use a function inlining pass.
/// VerifyEach - Run the verifier after each pass.
- static inline void createStandardLTOPasses(PassManager *PM,
+ static inline void createStandardLTOPasses(PassManagerBase *PM,
bool Internalize,
bool RunInliner,
bool VerifyEach);
// Implementations
- static inline void createStandardFunctionPasses(FunctionPassManager *PM,
+ static inline void createStandardFunctionPasses(PassManagerBase *PM,
unsigned OptimizationLevel) {
if (OptimizationLevel > 0) {
PM->add(createCFGSimplificationPass());
@@ -82,7 +82,7 @@ namespace llvm {
/// createStandardModulePasses - Add the standard module passes. This is
/// expected to be run after the standard function passes.
- static inline void createStandardModulePasses(PassManager *PM,
+ static inline void createStandardModulePasses(PassManagerBase *PM,
unsigned OptimizationLevel,
bool OptimizeSize,
bool UnitAtATime,
@@ -164,14 +164,14 @@ namespace llvm {
}
}
- static inline void addOnePass(PassManager *PM, Pass *P, bool AndVerify) {
+ static inline void addOnePass(PassManagerBase *PM, Pass *P, bool AndVerify) {
PM->add(P);
if (AndVerify)
PM->add(createVerifierPass());
}
- static inline void createStandardLTOPasses(PassManager *PM,
+ static inline void createStandardLTOPasses(PassManagerBase *PM,
bool Internalize,
bool RunInliner,
bool VerifyEach) {
diff --git a/include/llvm/System/Signals.h b/include/llvm/System/Signals.h
index 2b9d8ca..504420c 100644
--- a/include/llvm/System/Signals.h
+++ b/include/llvm/System/Signals.h
@@ -20,6 +20,10 @@
namespace llvm {
namespace sys {
+ /// This function runs all the registered interrupt handlers, including the
+ /// removal of files registered by RemoveFileOnSignal.
+ void RunInterruptHandlers();
+
/// This function registers signal handlers to ensure that if a signal gets
/// delivered that the named file is removed.
/// @brief Remove a file if a fatal signal occurs.
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
index 38a3cc2..4546871 100644
--- a/include/llvm/Target/SubtargetFeature.h
+++ b/include/llvm/Target/SubtargetFeature.h
@@ -108,9 +108,10 @@ public:
// Dump feature info.
void dump() const;
- /// Retrieve a formatted string of the default features for
- /// the specified target triple.
- static std::string getDefaultSubtargetFeatures(const Triple &Triple);
+ /// Retrieve a formatted string of the default features for the specified
+ /// target triple.
+ void getDefaultSubtargetFeatures(const std::string &CPU,
+ const Triple& Triple);
};
} // End namespace llvm
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index cc19e0d..ca551e5 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -21,6 +21,11 @@ include "llvm/Intrinsics.td"
class RegisterClass; // Forward def
+// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
+class SubRegIndex {
+ string Namespace = "";
+}
+
// Register - You should define one instance of this class for each register
// in the target machine. String n will become the "name" of the register.
class Register<string n> {
@@ -49,6 +54,23 @@ class Register<string n> {
// not [AX, AH, AL].
list<Register> SubRegs = [];
+ // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used
+ // to address it. Sub-sub-register indices are automatically inherited from
+ // SubRegs.
+ list<SubRegIndex> SubRegIndices = [];
+
+ // 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
@@ -68,17 +90,6 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
}
-// SubRegSet - This can be used to define a specific mapping of registers to
-// indices, for use as named subregs of a particular physical register. Each
-// register in 'subregs' becomes an addressable subregister at index 'n' of the
-// corresponding register in 'regs'.
-class SubRegSet<int n, list<Register> regs, list<Register> subregs> {
- int index = n;
-
- list<Register> From = regs;
- list<Register> To = subregs;
-}
-
// 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
@@ -117,9 +128,9 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
list<Register> MemberList = regList;
- // SubClassList - Specify which register classes correspond to subregisters
- // of this class. The order should be by subregister set index.
- list<RegisterClass> SubRegClassList = [];
+ // SubRegClasses - Specify the register class of subregisters as a list of
+ // dags: (RegClass SubRegIndex, SubRegindex, ...)
+ list<dag> SubRegClasses = [];
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
// code into a generated register class. The normal usage of this is to
@@ -221,6 +232,9 @@ class Instruction {
// purposes.
bit isCodeGenOnly = 0;
+ // Is this instruction a pseudo instruction for use by the assembler parser.
+ bit isAsmParserOnly = 0;
+
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
@@ -296,8 +310,8 @@ class AsmOperandClass {
/// The name to use for this class, which should be usable as an enum value.
string Name = ?;
- /// The super class of this operand.
- AsmOperandClass SuperClass = ?;
+ /// The super classes of this operand.
+ list<AsmOperandClass> SuperClasses = [];
/// The name of the method on the target specific operand to call to test
/// whether the operand is an instance of this class. If not set, this will
@@ -331,10 +345,10 @@ class Operand<ValueType ty> {
// in. Match classes are used to define the order in which instructions are
// match, to ensure that which instructions gets matched is deterministic.
//
- // The target specific parser must be able to classify an parsed operand
- // into a unique class, which does not partially overlap with any other
- // classes. It can match a subset of some other class, in which case
- // ParserMatchSuperClass should be set to the name of that class.
+ // The target specific parser must be able to classify an parsed operand into
+ // a unique class, which does not partially overlap with any other classes. It
+ // can match a subset of some other class, in which case the AsmOperandClass
+ // should declare the other operand as one of its super classes.
AsmOperandClass ParserMatchClass = ImmAsmOperand;
}
diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h
index f350ecc..979595a 100644
--- a/include/llvm/Target/TargetAsmBackend.h
+++ b/include/llvm/Target/TargetAsmBackend.h
@@ -13,10 +13,9 @@
#include "llvm/System/DataTypes.h"
namespace llvm {
-class MCAsmFixup;
class MCDataFragment;
+class MCFixup;
class MCInst;
-class MCInstFragment;
class MCObjectWriter;
class MCSection;
template<typename T>
@@ -90,6 +89,14 @@ public:
return false;
}
+ /// isSectionAtomizable - Check whether the given section can be split into
+ /// atoms.
+ ///
+ /// \see MCAssembler::isSymbolLinkerVisible().
+ virtual bool isSectionAtomizable(const MCSection &Section) const {
+ return true;
+ }
+
/// isVirtualSection - Check whether the given section is "virtual", that is
/// has no actual object file contents.
virtual bool isVirtualSection(const MCSection &Section) const = 0;
@@ -97,22 +104,22 @@ public:
/// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
- virtual void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &Fragment,
+ virtual void ApplyFixup(const MCFixup &Fixup, MCDataFragment &Fragment,
uint64_t Value) const = 0;
/// MayNeedRelaxation - Check whether the given instruction may need
/// relaxation.
///
- /// \arg Inst - The instruction to test.
- /// \arg Fixups - The actual fixups this instruction encoded to, for potential
- /// use by the target backend.
- virtual bool MayNeedRelaxation(const MCInst &Inst,
- const SmallVectorImpl<MCAsmFixup> &Fixups) const = 0;
+ /// \param Inst - The instruction to test.
+ virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0;
/// RelaxInstruction - Relax the instruction in the given fragment to the next
/// wider instruction.
- virtual void RelaxInstruction(const MCInstFragment *IF,
- MCInst &Res) const = 0;
+ ///
+ /// \param Inst - The instruction to relax, which may be the same as the
+ /// output.
+ /// \parm Res [output] - On return, the relaxed instruction.
+ virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
/// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
/// output. If the target cannot generate such a sequence, it should return an
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 143dbcc..2e5697e 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -315,7 +315,8 @@ public:
MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
- const TargetRegisterClass *SrcRC) const {
+ const TargetRegisterClass *SrcRC,
+ DebugLoc DL) const {
assert(0 && "Target didn't implement TargetInstrInfo::copyRegToReg!");
return false;
}
@@ -328,7 +329,8 @@ public:
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIndex,
- const TargetRegisterClass *RC) const {
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
}
@@ -339,7 +341,8 @@ public:
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIndex,
- const TargetRegisterClass *RC) const {
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
}
@@ -349,7 +352,8 @@ public:
/// storeRegToStackSlot(). Returns false otherwise.
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI) const {
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
return false;
}
@@ -359,7 +363,8 @@ public:
/// Returns false otherwise.
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI) const {
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
return false;
}
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 4ea6c94..5efebe6 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -55,7 +55,6 @@ namespace llvm {
class TargetData;
class TargetMachine;
class TargetRegisterClass;
- class TargetSubtarget;
class TargetLoweringObjectFile;
class Value;
@@ -98,11 +97,6 @@ public:
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
- enum SchedPreference {
- SchedulingForLatency, // Scheduling for shortest total latency.
- SchedulingForRegPressure // Scheduling for lowest register pressure.
- };
-
/// NOTE: The constructor takes ownership of TLOF.
explicit TargetLowering(const TargetMachine &TM,
const TargetLoweringObjectFile *TLOF);
@@ -151,13 +145,20 @@ public:
BooleanContent getBooleanContents() const { return BooleanContents;}
/// getSchedulingPreference - Return target scheduling preference.
- SchedPreference getSchedulingPreference() const {
+ Sched::Preference getSchedulingPreference() const {
return SchedPreferenceInfo;
}
+ /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to
+ /// different scheduling heuristics for different nodes. This function returns
+ /// the preference (or none) for the given node.
+ virtual Sched::Preference getSchedulingPreference(SDNode *N) const {
+ return Sched::None;
+ }
+
/// getRegClassFor - Return the register class that should be used for the
- /// specified value type. This may only be called on legal types.
- TargetRegisterClass *getRegClassFor(EVT VT) const {
+ /// specified value type.
+ virtual TargetRegisterClass *getRegClassFor(EVT VT) const {
assert(VT.isSimple() && "getRegClassFor called on illegal type!");
TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
assert(RC && "This value type is not natively supported!");
@@ -181,11 +182,9 @@ public:
}
class ValueTypeActionImpl {
- /// ValueTypeActions - This is a bitvector that contains two bits for each
- /// value type, where the two bits correspond to the LegalizeAction enum.
- /// This can be queried with "getTypeAction(VT)".
- /// dimension by (MVT::MAX_ALLOWED_VALUETYPE/32) * 2
- uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2];
+ /// ValueTypeActions - For each value type, keep a LegalizeAction enum
+ /// that indicates how instruction selection should deal with the type.
+ uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
public:
ValueTypeActionImpl() {
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
@@ -202,13 +201,11 @@ public:
return Legal;
}
unsigned I = VT.getSimpleVT().SimpleTy;
- assert(I<4*array_lengthof(ValueTypeActions)*sizeof(ValueTypeActions[0]));
- return (LegalizeAction)((ValueTypeActions[I>>4] >> ((2*I) & 31)) & 3);
+ return (LegalizeAction)ValueTypeActions[I];
}
void setTypeAction(EVT VT, LegalizeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
- assert(I<4*array_lengthof(ValueTypeActions)*sizeof(ValueTypeActions[0]));
- ValueTypeActions[I>>4] |= Action << ((I*2) & 31);
+ ValueTypeActions[I] = Action;
}
};
@@ -357,13 +354,9 @@ public:
/// for it.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const {
if (VT.isExtended()) return Expand;
- assert(Op < array_lengthof(OpActions[0]) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(OpActions[0][0])*8 &&
- "Table isn't big enough!");
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
- unsigned J = I & 31;
- I = I >> 5;
- return (LegalizeAction)((OpActions[I][Op] >> (J*2) ) & 3);
+ return (LegalizeAction)OpActions[I][Op];
}
/// isOperationLegalOrCustom - Return true if the specified operation is
@@ -386,35 +379,31 @@ public:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
- LegalizeAction getLoadExtAction(unsigned LType, EVT VT) const {
- assert(LType < array_lengthof(LoadExtActions) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(LoadExtActions[0])*4 &&
+ LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
+ (unsigned)VT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((LoadExtActions[LType] >>
- (2*VT.getSimpleVT().SimpleTy)) & 3);
+ return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtType];
}
/// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
- bool isLoadExtLegal(unsigned LType, EVT VT) const {
+ bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
return VT.isSimple() &&
- (getLoadExtAction(LType, VT) == Legal ||
- getLoadExtAction(LType, VT) == Custom);
+ (getLoadExtAction(ExtType, VT) == Legal ||
+ getLoadExtAction(ExtType, VT) == Custom);
}
/// getTruncStoreAction - Return how this store with truncation should be
/// treated: either it is legal, needs to be promoted to a larger size, needs
/// to be expanded to some other code sequence, or the target has a custom
/// expander for it.
- LegalizeAction getTruncStoreAction(EVT ValVT,
- EVT MemVT) const {
- assert((unsigned)ValVT.getSimpleVT().SimpleTy <
- array_lengthof(TruncStoreActions) &&
- (unsigned)MemVT.getSimpleVT().SimpleTy <
- sizeof(TruncStoreActions[0])*4 &&
+ LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
+ assert((unsigned)ValVT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
+ (unsigned)MemVT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((TruncStoreActions[ValVT.getSimpleVT().SimpleTy] >>
- (2*MemVT.getSimpleVT().SimpleTy)) & 3);
+ return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy]
+ [MemVT.getSimpleVT().SimpleTy];
}
/// isTruncStoreLegal - Return true if the specified store with truncation is
@@ -431,11 +420,11 @@ public:
/// for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, EVT VT) const {
- assert( IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
+ assert( IdxMode < ISD::LAST_INDEXED_MODE &&
((unsigned)VT.getSimpleVT().SimpleTy) < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[
- (unsigned)VT.getSimpleVT().SimpleTy][0][IdxMode]));
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
}
/// isIndexedLoadLegal - Return true if the specified indexed load is legal
@@ -452,11 +441,11 @@ public:
/// for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < array_lengthof(IndexedModeActions[0][1]) &&
- (unsigned)VT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
+ assert( IdxMode < ISD::LAST_INDEXED_MODE &&
+ ((unsigned)VT.getSimpleVT().SimpleTy) < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[
- (unsigned)VT.getSimpleVT().SimpleTy][1][IdxMode]));
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
}
/// isIndexedStoreLegal - Return true if the specified indexed load is legal
@@ -919,7 +908,7 @@ protected:
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
/// setSchedulingPreference - Specify the target scheduling preference.
- void setSchedulingPreference(SchedPreference Pref) {
+ void setSchedulingPreference(Sched::Preference Pref) {
SchedPreferenceInfo = Pref;
}
@@ -991,33 +980,28 @@ protected:
/// with the specified type and indicate what to do about it.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
- unsigned I = (unsigned)VT.SimpleTy;
- unsigned J = I & 31;
- I = I >> 5;
- OpActions[I][Op] &= ~(uint64_t(3UL) << (J*2));
- OpActions[I][Op] |= (uint64_t)Action << (J*2);
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
}
/// setLoadExtAction - Indicate that the specified load with extension does
/// not work with the specified type and indicate what to do about it.
void setLoadExtAction(unsigned ExtType, MVT VT,
- LegalizeAction Action) {
- assert((unsigned)VT.SimpleTy*2 < 63 &&
- ExtType < array_lengthof(LoadExtActions) &&
+ LegalizeAction Action) {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
+ (unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.SimpleTy*2);
- LoadExtActions[ExtType] |= (uint64_t)Action << VT.SimpleTy*2;
+ LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
}
/// setTruncStoreAction - Indicate that the specified truncating store does
/// not work with the specified type and indicate what to do about it.
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
- assert((unsigned)ValVT.SimpleTy < array_lengthof(TruncStoreActions) &&
- (unsigned)MemVT.SimpleTy*2 < 63 &&
+ assert((unsigned)ValVT.SimpleTy < MVT::LAST_VALUETYPE &&
+ (unsigned)MemVT.SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- TruncStoreActions[ValVT.SimpleTy] &= ~(uint64_t(3UL) << MemVT.SimpleTy*2);
- TruncStoreActions[ValVT.SimpleTy] |= (uint64_t)Action << MemVT.SimpleTy*2;
+ TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
}
/// setIndexedLoadAction - Indicate that the specified indexed load does or
@@ -1027,9 +1011,12 @@ protected:
void setIndexedLoadAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
- IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
+ IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf &&
"Table isn't big enough!");
- IndexedModeActions[(unsigned)VT.SimpleTy][0][IdxMode] = (uint8_t)Action;
+ // Load action are kept in the upper half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4;
}
/// setIndexedStoreAction - Indicate that the specified indexed store does or
@@ -1039,9 +1026,12 @@ protected:
void setIndexedStoreAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
- IdxMode < array_lengthof(IndexedModeActions[0][1] ) &&
+ IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf &&
"Table isn't big enough!");
- IndexedModeActions[(unsigned)VT.SimpleTy][1][IdxMode] = (uint8_t)Action;
+ // Store action are kept in the lower half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action);
}
/// setCondCodeAction - Indicate that the specified condition code is or isn't
@@ -1103,12 +1093,6 @@ protected:
}
public:
-
- virtual const TargetSubtarget *getSubtarget() const {
- assert(0 && "Not Implemented");
- return NULL; // this is here to silence compiler errors
- }
-
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
// the SelectionDAGLowering code knows how to lower these.
@@ -1200,61 +1184,6 @@ public:
return SDValue(); // this is here to silence compiler errors
}
- /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
- /// memcpy. This can be used by targets to provide code sequences for cases
- /// that don't fit the target's parameters for simple loads/stores and can be
- /// more efficient than using a library call. This function can return a null
- /// SDValue if the target declines to use custom code and a different
- /// lowering strategy should be used.
- ///
- /// If AlwaysInline is true, the size is constant and the target should not
- /// emit any calls and is strongly encouraged to attempt to emit inline code
- /// even if it is beyond the usual threshold because this intrinsic is being
- /// expanded in a place where calls are not feasible (e.g. within the prologue
- /// for another call). If the target chooses to decline an AlwaysInline
- /// request here, legalize will resort to using simple loads and stores.
- virtual SDValue
- EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain,
- SDValue Op1, SDValue Op2,
- SDValue Op3, unsigned Align, bool isVolatile,
- bool AlwaysInline,
- const Value *DstSV, uint64_t DstOff,
- const Value *SrcSV, uint64_t SrcOff) const {
- return SDValue();
- }
-
- /// EmitTargetCodeForMemmove - Emit target-specific code that performs a
- /// memmove. This can be used by targets to provide code sequences for cases
- /// that don't fit the target's parameters for simple loads/stores and can be
- /// more efficient than using a library call. This function can return a null
- /// SDValue if the target declines to use custom code and a different
- /// lowering strategy should be used.
- virtual SDValue
- EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain,
- SDValue Op1, SDValue Op2,
- SDValue Op3, unsigned Align, bool isVolatile,
- const Value *DstSV, uint64_t DstOff,
- const Value *SrcSV, uint64_t SrcOff) const {
- return SDValue();
- }
-
- /// EmitTargetCodeForMemset - Emit target-specific code that performs a
- /// memset. This can be used by targets to provide code sequences for cases
- /// that don't fit the target's parameters for simple stores and can be more
- /// efficient than using a library call. This function can return a null
- /// SDValue if the target declines to use custom code and a different
- /// lowering strategy should be used.
- virtual SDValue
- EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain,
- SDValue Op1, SDValue Op2,
- SDValue Op3, unsigned Align, bool isVolatile,
- const Value *DstSV, uint64_t DstOff) const {
- return SDValue();
- }
-
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.
@@ -1594,7 +1523,7 @@ private:
/// SchedPreferenceInfo - The target scheduling preference: shortest possible
/// total cycles or lowest register usage.
- SchedPreference SchedPreferenceInfo;
+ Sched::Preference SchedPreferenceInfo;
/// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
unsigned JumpBufSize;
@@ -1653,26 +1582,24 @@ private:
/// Most operations are Legal (aka, supported natively by the target), but
/// operations that are not should be described. Note that operations on
/// non-legal value types are not described here.
- /// This array is accessed using VT.getSimpleVT(), so it is subject to
- /// the MVT::MAX_ALLOWED_VALUETYPE * 2 bits.
- uint64_t OpActions[MVT::MAX_ALLOWED_VALUETYPE/(sizeof(uint64_t)*4)][ISD::BUILTIN_OP_END];
+ uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
- /// LoadExtActions - For each load of load extension type and each value type,
+ /// LoadExtActions - For each load extension type and each value type,
/// keep a LegalizeAction that indicates how instruction selection should deal
- /// with the load.
- uint64_t LoadExtActions[ISD::LAST_LOADEXT_TYPE];
+ /// with a load of a specific value type and extension type.
+ uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
- /// TruncStoreActions - For each truncating store, keep a LegalizeAction that
- /// indicates how instruction selection should deal with the store.
- uint64_t TruncStoreActions[MVT::LAST_VALUETYPE];
+ /// TruncStoreActions - For each value type pair keep a LegalizeAction that
+ /// indicates whether a truncating store of a specific value type and
+ /// truncating type is legal.
+ uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
/// IndexedModeActions - For each indexed mode and each value type,
/// keep a pair of LegalizeAction that indicates how instruction
- /// selection should deal with the load / store. The first
- /// dimension is now the value_type for the reference. The second
- /// dimension is the load [0] vs. store[1]. The third dimension
- /// represents the various modes for load store.
- uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][2][ISD::LAST_INDEXED_MODE];
+ /// selection should deal with the load / store. The first dimension is the
+ /// value_type for the reference. The second dimension represents the various
+ /// modes for load store.
+ uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE];
/// CondCodeActions - For each condition code (ISD::CondCode) keep a
/// LegalizeAction that indicates how instruction selection should
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 6c99598..819709f 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -88,6 +88,10 @@ protected:
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
+ // Extra TLS Variable Data section. If the target needs to put additional
+ // information for a TLS variable, it'll go here.
+ const MCSection *TLSExtraDataSection;
+
/// SupportsWeakEmptyEHFrame - True if target object file supports a
/// weak_definition of constant 0 for an omitted EH frame.
bool SupportsWeakOmittedEHFrame;
@@ -147,6 +151,9 @@ public:
const MCSection *getDwarfMacroInfoSection() const {
return DwarfMacroInfoSection;
}
+ const MCSection *getTLSExtraDataSection() const {
+ return TLSExtraDataSection;
+ }
/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
/// decide not to emit the UsedDirective for some symbols in llvm.used.
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index c734cf4..227499b 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -70,6 +70,15 @@ namespace CodeGenOpt {
};
}
+namespace Sched {
+ enum Preference {
+ None, // No preference
+ Latency, // Scheduling for shortest total latency.
+ RegPressure, // Scheduling for lowest register pressure.
+ Hybrid // Scheduling for both latency and register pressure.
+ };
+}
+
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
@@ -92,7 +101,9 @@ protected: // Can only create subclasses.
/// AsmInfo - Contains target specific asm information.
///
const MCAsmInfo *AsmInfo;
-
+
+ unsigned MCRelaxAll : 1;
+
public:
virtual ~TargetMachine();
@@ -149,6 +160,14 @@ public:
///
virtual const TargetELFWriterInfo *getELFWriterInfo() const { return 0; }
+ /// hasMCRelaxAll - Check whether all machine code instructions should be
+ /// relaxed.
+ bool hasMCRelaxAll() const { return MCRelaxAll; }
+
+ /// setMCRelaxAll - Set whether all machine code instructions should be
+ /// relaxed.
+ void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
+
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
static Reloc::Model getRelocationModel();
@@ -225,17 +244,6 @@ public:
bool = true) {
return true;
}
-
- /// addPassesToEmitWholeFile - This method can be implemented by targets that
- /// require having the entire module at once. This is not recommended, do not
- /// use this.
- virtual bool WantsWholeFile() const { return false; }
- virtual bool addPassesToEmitWholeFile(PassManager &, formatted_raw_ostream &,
- CodeGenFileType,
- CodeGenOpt::Level,
- bool = true) {
- return true;
- }
};
/// LLVMTargetMachine - This class describes a target machine that is
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 29b862a..7c37b73 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -28,6 +28,7 @@ class BitVector;
class MachineFunction;
class MachineMove;
class RegScavenger;
+template<class T> class SmallVectorImpl;
/// TargetRegisterDesc - This record contains all of the information known about
/// a particular register. The AliasSet field (if not null) contains a pointer
@@ -151,9 +152,6 @@ public:
/// index SubIdx, or NULL if no such class exists.
const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const {
assert(SubIdx>0 && "Invalid subregister index");
- for (unsigned s = 0; s != SubIdx-1; ++s)
- if (!SubRegClasses[s])
- return NULL;
return SubRegClasses[SubIdx-1];
}
@@ -262,14 +260,13 @@ class TargetRegisterInfo {
protected:
const unsigned* SubregHash;
const unsigned SubregHashSize;
- const unsigned* SuperregHash;
- const unsigned SuperregHashSize;
const unsigned* AliasesHash;
const unsigned AliasesHashSize;
public:
typedef const TargetRegisterClass * const * regclass_iterator;
private:
const TargetRegisterDesc *Desc; // Pointer to the descriptor array
+ const char *const *SubRegIndexNames; // Names of subreg indexes.
unsigned NumRegs; // Number of entries in the array
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
@@ -280,12 +277,11 @@ protected:
TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
regclass_iterator RegClassBegin,
regclass_iterator RegClassEnd,
+ const char *const *subregindexnames,
int CallFrameSetupOpcode = -1,
int CallFrameDestroyOpcode = -1,
const unsigned* subregs = 0,
const unsigned subregsize = 0,
- const unsigned* superregs = 0,
- const unsigned superregsize = 0,
const unsigned* aliases = 0,
const unsigned aliasessize = 0);
virtual ~TargetRegisterInfo();
@@ -380,6 +376,13 @@ public:
return NumRegs;
}
+ /// getSubRegIndexName - Return the human-readable symbolic target-specific
+ /// name for the specified SubRegIndex.
+ const char *getSubRegIndexName(unsigned SubIdx) const {
+ assert(SubIdx && "This is not a subregister index");
+ return SubRegIndexNames[SubIdx-1];
+ }
+
/// regsOverlap - Returns true if the two registers are equal or alias each
/// other. The registers may be virtual register.
bool regsOverlap(unsigned regA, unsigned regB) const {
@@ -425,19 +428,7 @@ public:
/// isSuperRegister - Returns true if regB is a super-register of regA.
///
bool isSuperRegister(unsigned regA, unsigned regB) const {
- // SuperregHash is a simple quadratically probed hash table.
- size_t index = (regA + regB * 37) & (SuperregHashSize-1);
- unsigned ProbeAmt = 2;
- while (SuperregHash[index*2] != 0 &&
- SuperregHash[index*2+1] != 0) {
- if (SuperregHash[index*2] == regA && SuperregHash[index*2+1] == regB)
- return true;
-
- index = (index + ProbeAmt) & (SuperregHashSize-1);
- ProbeAmt += 2;
- }
-
- return false;
+ return isSubRegister(regB, regA);
}
/// getCalleeSavedRegs - Return a null-terminated list of all of the
@@ -479,6 +470,17 @@ public:
return 0;
}
+ /// canCombinedSubRegIndex - Given a register class and a list of sub-register
+ /// indices, return true if it's possible to combine the sub-register indices
+ /// into one that corresponds to a larger sub-register. Return the new sub-
+ /// register index by reference. Note the new index by be zero if the given
+ /// sub-registers combined to form the whole register.
+ virtual bool canCombinedSubRegIndex(const TargetRegisterClass *RC,
+ SmallVectorImpl<unsigned> &SubIndices,
+ unsigned &NewSubIdx) const {
+ return 0;
+ }
+
/// getMatchingSuperRegClass - Return a subclass of the specified register
/// class A so that each register in it has a sub-register of the
/// specified sub-register index which is in the specified register class B.
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index 36bbe00..1418bee 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -73,6 +73,13 @@ namespace llvm {
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
TargetMachine &TM,
MCContext &Ctx);
+ typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T,
+ const std::string &TT,
+ MCContext &Ctx,
+ TargetAsmBackend &TAB,
+ raw_ostream &_OS,
+ MCCodeEmitter *_Emitter,
+ bool RelaxAll);
private:
/// Next - The next registered target in the linked list, maintained by the
@@ -126,6 +133,10 @@ namespace llvm {
/// if registered.
CodeEmitterCtorTy CodeEmitterCtorFn;
+ /// ObjectStreamerCtorFn - Construction function for this target's
+ /// ObjectStreamer, if registered.
+ ObjectStreamerCtorTy ObjectStreamerCtorFn;
+
public:
/// @name Target Information
/// @{
@@ -170,6 +181,9 @@ namespace llvm {
/// hasCodeEmitter - Check if this target supports instruction encoding.
bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
+ /// hasObjectStreamer - Check if this target supports streaming to files.
+ bool hasObjectStreamer() const { return ObjectStreamerCtorFn != 0; }
+
/// @}
/// @name Feature Constructors
/// @{
@@ -258,6 +272,24 @@ namespace llvm {
return CodeEmitterCtorFn(*this, TM, Ctx);
}
+ /// createObjectStreamer - Create a target specific MCStreamer.
+ ///
+ /// \arg TT - The target triple.
+ /// \arg Ctx - The target context.
+ /// \arg TAB - The target assembler backend object.
+ /// \arg _OS - The stream object.
+ /// \arg _Emitter - The target independent assembler object.
+ /// \arg RelaxAll - Relax all fixups?
+ MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
+ TargetAsmBackend &TAB,
+ raw_ostream &_OS,
+ MCCodeEmitter *_Emitter,
+ bool RelaxAll) const {
+ if (!ObjectStreamerCtorFn)
+ return 0;
+ return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
+ }
+
/// @}
};
@@ -479,6 +511,20 @@ namespace llvm {
T.CodeEmitterCtorFn = Fn;
}
+ /// RegisterObjectStreamer - Register an MCStreamer implementation
+ /// for the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCStreamer for the target.
+ static void RegisterObjectStreamer(Target &T, Target::ObjectStreamerCtorTy Fn) {
+ if (!T.ObjectStreamerCtorFn)
+ T.ObjectStreamerCtorFn = Fn;
+ }
+
/// @}
};
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index 943bdea..2be1834 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -16,19 +16,84 @@
#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H
#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
namespace llvm {
+class TargetData;
+class TargetMachine;
+
//===----------------------------------------------------------------------===//
-/// TargetSelectionDAGLowering - Targets can subclass this to parameterize the
+/// TargetSelectionDAGInfo - Targets can subclass this to parameterize the
/// SelectionDAG lowering and instruction selection process.
///
class TargetSelectionDAGInfo {
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
+ const TargetData *TD;
+
+protected:
+ const TargetData *getTargetData() const { return TD; }
+
public:
- TargetSelectionDAGInfo();
+ explicit TargetSelectionDAGInfo(const TargetMachine &TM);
virtual ~TargetSelectionDAGInfo();
+
+ /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
+ /// memcpy. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple loads/stores and can be
+ /// more efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ ///
+ /// If AlwaysInline is true, the size is constant and the target should not
+ /// emit any calls and is strongly encouraged to attempt to emit inline code
+ /// even if it is beyond the usual threshold because this intrinsic is being
+ /// expanded in a place where calls are not feasible (e.g. within the prologue
+ /// for another call). If the target chooses to decline an AlwaysInline
+ /// request here, legalize will resort to using simple loads and stores.
+ virtual SDValue
+ EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ bool AlwaysInline,
+ const Value *DstSV, uint64_t DstOff,
+ const Value *SrcSV, uint64_t SrcOff) const {
+ return SDValue();
+ }
+
+ /// EmitTargetCodeForMemmove - Emit target-specific code that performs a
+ /// memmove. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple loads/stores and can be
+ /// more efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ virtual SDValue
+ EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ const Value *DstSV, uint64_t DstOff,
+ const Value *SrcSV, uint64_t SrcOff) const {
+ return SDValue();
+ }
+
+ /// EmitTargetCodeForMemset - Emit target-specific code that performs a
+ /// memset. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple stores and can be more
+ /// efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ virtual SDValue
+ EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ const Value *DstSV, uint64_t DstOff) const {
+ return SDValue();
+ }
};
} // end llvm namespace
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index a8c9c6a..0d338b5 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -332,6 +332,12 @@ FunctionPass *createGEPSplitterPass();
//
FunctionPass *createABCDPass();
+//===----------------------------------------------------------------------===//
+//
+// Sink - Code Sinking
+//
+FunctionPass *createSinkingPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index 5b77ed6..ca98466 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -19,8 +19,8 @@ namespace llvm {
class BasicBlock;
class Use;
class PHINode;
- template<typename T>
- class SmallVectorImpl;
+ template<typename T> class SmallVectorImpl;
+ template<typename T> class SSAUpdaterTraits;
class BumpPtrAllocator;
/// SSAUpdater - This class updates SSA form for a set of values defined in
@@ -28,9 +28,7 @@ namespace llvm {
/// transformation wants to rewrite a set of uses of one value with uses of a
/// set of values.
class SSAUpdater {
-public:
- class BBInfo;
- typedef SmallVectorImpl<BBInfo*> BlockListTy;
+ friend class SSAUpdaterTraits<SSAUpdater>;
private:
/// AvailableVals - This keeps track of which value to use on a per-block
@@ -42,14 +40,10 @@ private:
/// and a type for PHI nodes.
Value *PrototypeValue;
- /// BBMap - The GetValueAtEndOfBlock method maintains this mapping from
- /// basic blocks to BBInfo structures.
- /// typedef DenseMap<BasicBlock*, BBInfo*> BBMapTy;
- void *BM;
-
/// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
/// it creates to the vector.
SmallVectorImpl<PHINode*> *InsertedPHIs;
+
public:
/// SSAUpdater constructor. If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
@@ -102,14 +96,6 @@ public:
private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
- void BuildBlockList(BasicBlock *BB, BlockListTy *BlockList,
- BumpPtrAllocator *Allocator);
- void FindDominators(BlockListTy *BlockList);
- void FindPHIPlacement(BlockListTy *BlockList);
- void FindAvailableVals(BlockListTy *BlockList);
- void FindExistingPHI(BasicBlock *BB, BlockListTy *BlockList);
- bool CheckIfPHIMatches(PHINode *PHI);
- void RecordMatchingPHI(PHINode *PHI);
void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT
diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
new file mode 100644
index 0000000..5a03d22
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -0,0 +1,469 @@
+//===-- SSAUpdaterImpl.h - SSA Updater Implementation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a template that implements the core algorithm for the
+// SSAUpdater and MachineSSAUpdater.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+
+namespace llvm {
+
+template<typename T> class SSAUpdaterTraits;
+
+template<typename UpdaterT>
+class SSAUpdaterImpl {
+private:
+ UpdaterT *Updater;
+
+ typedef SSAUpdaterTraits<UpdaterT> Traits;
+ typedef typename Traits::BlkT BlkT;
+ typedef typename Traits::ValT ValT;
+ typedef typename Traits::PhiT PhiT;
+
+ /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
+ /// The predecessors of each block are cached here since pred_iterator is
+ /// slow and we need to iterate over the blocks at least a few times.
+ class BBInfo {
+ public:
+ BlkT *BB; // Back-pointer to the corresponding block.
+ ValT AvailableVal; // Value to use in this block.
+ BBInfo *DefBB; // Block that defines the available value.
+ int BlkNum; // Postorder number.
+ BBInfo *IDom; // Immediate dominator.
+ unsigned NumPreds; // Number of predecessor blocks.
+ BBInfo **Preds; // Array[NumPreds] of predecessor blocks.
+ PhiT *PHITag; // Marker for existing PHIs that match.
+
+ BBInfo(BlkT *ThisBB, ValT V)
+ : BB(ThisBB), AvailableVal(V), DefBB(V ? this : 0), BlkNum(0), IDom(0),
+ NumPreds(0), Preds(0), PHITag(0) { }
+ };
+
+ typedef DenseMap<BlkT*, ValT> AvailableValsTy;
+ AvailableValsTy *AvailableVals;
+
+ SmallVectorImpl<PhiT*> *InsertedPHIs;
+
+ typedef SmallVectorImpl<BBInfo*> BlockListTy;
+ typedef DenseMap<BlkT*, BBInfo*> BBMapTy;
+ BBMapTy BBMap;
+ BumpPtrAllocator Allocator;
+
+public:
+ explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
+ SmallVectorImpl<PhiT*> *Ins) :
+ Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
+
+ /// GetValue - Check to see if AvailableVals has an entry for the specified
+ /// BB and if so, return it. If not, construct SSA form by first
+ /// calculating the required placement of PHIs and then inserting new PHIs
+ /// where needed.
+ ValT GetValue(BlkT *BB) {
+ SmallVector<BBInfo*, 100> BlockList;
+ BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
+
+ // Special case: bail out if BB is unreachable.
+ if (BlockList.size() == 0) {
+ ValT V = Traits::GetUndefVal(BB, Updater);
+ (*AvailableVals)[BB] = V;
+ return V;
+ }
+
+ FindDominators(&BlockList, PseudoEntry);
+ FindPHIPlacement(&BlockList);
+ FindAvailableVals(&BlockList);
+
+ return BBMap[BB]->DefBB->AvailableVal;
+ }
+
+ /// BuildBlockList - Starting from the specified basic block, traverse back
+ /// through its predecessors until reaching blocks with known values.
+ /// Create BBInfo structures for the blocks and append them to the block
+ /// list.
+ BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
+ SmallVector<BBInfo*, 10> RootList;
+ SmallVector<BBInfo*, 64> WorkList;
+
+ BBInfo *Info = new (Allocator) BBInfo(BB, 0);
+ BBMap[BB] = Info;
+ WorkList.push_back(Info);
+
+ // Search backward from BB, creating BBInfos along the way and stopping
+ // when reaching blocks that define the value. Record those defining
+ // blocks on the RootList.
+ SmallVector<BlkT*, 10> Preds;
+ while (!WorkList.empty()) {
+ Info = WorkList.pop_back_val();
+ Preds.clear();
+ Traits::FindPredecessorBlocks(Info->BB, &Preds);
+ Info->NumPreds = Preds.size();
+ if (Info->NumPreds == 0)
+ Info->Preds = 0;
+ else
+ Info->Preds = static_cast<BBInfo**>
+ (Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
+ AlignOf<BBInfo*>::Alignment));
+
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BlkT *Pred = Preds[p];
+ // Check if BBMap already has a BBInfo for the predecessor block.
+ typename BBMapTy::value_type &BBMapBucket =
+ BBMap.FindAndConstruct(Pred);
+ if (BBMapBucket.second) {
+ Info->Preds[p] = BBMapBucket.second;
+ continue;
+ }
+
+ // Create a new BBInfo for the predecessor.
+ ValT PredVal = AvailableVals->lookup(Pred);
+ BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
+ BBMapBucket.second = PredInfo;
+ Info->Preds[p] = PredInfo;
+
+ if (PredInfo->AvailableVal) {
+ RootList.push_back(PredInfo);
+ continue;
+ }
+ WorkList.push_back(PredInfo);
+ }
+ }
+
+ // Now that we know what blocks are backwards-reachable from the starting
+ // block, do a forward depth-first traversal to assign postorder numbers
+ // to those blocks.
+ BBInfo *PseudoEntry = new (Allocator) BBInfo(0, 0);
+ unsigned BlkNum = 1;
+
+ // Initialize the worklist with the roots from the backward traversal.
+ while (!RootList.empty()) {
+ Info = RootList.pop_back_val();
+ Info->IDom = PseudoEntry;
+ Info->BlkNum = -1;
+ WorkList.push_back(Info);
+ }
+
+ while (!WorkList.empty()) {
+ Info = WorkList.back();
+
+ if (Info->BlkNum == -2) {
+ // All the successors have been handled; assign the postorder number.
+ Info->BlkNum = BlkNum++;
+ // If not a root, put it on the BlockList.
+ if (!Info->AvailableVal)
+ BlockList->push_back(Info);
+ WorkList.pop_back();
+ continue;
+ }
+
+ // Leave this entry on the worklist, but set its BlkNum to mark that its
+ // successors have been put on the worklist. When it returns to the top
+ // the list, after handling its successors, it will be assigned a
+ // number.
+ Info->BlkNum = -2;
+
+ // Add unvisited successors to the work list.
+ for (typename Traits::BlkSucc_iterator SI =
+ Traits::BlkSucc_begin(Info->BB),
+ E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
+ BBInfo *SuccInfo = BBMap[*SI];
+ if (!SuccInfo || SuccInfo->BlkNum)
+ continue;
+ SuccInfo->BlkNum = -1;
+ WorkList.push_back(SuccInfo);
+ }
+ }
+ PseudoEntry->BlkNum = BlkNum;
+ return PseudoEntry;
+ }
+
+ /// IntersectDominators - This is the dataflow lattice "meet" operation for
+ /// finding dominators. Given two basic blocks, it walks up the dominator
+ /// tree until it finds a common dominator of both. It uses the postorder
+ /// number of the blocks to determine how to do that.
+ BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
+ while (Blk1 != Blk2) {
+ while (Blk1->BlkNum < Blk2->BlkNum) {
+ Blk1 = Blk1->IDom;
+ if (!Blk1)
+ return Blk2;
+ }
+ while (Blk2->BlkNum < Blk1->BlkNum) {
+ Blk2 = Blk2->IDom;
+ if (!Blk2)
+ return Blk1;
+ }
+ }
+ return Blk1;
+ }
+
+ /// FindDominators - Calculate the dominator tree for the subset of the CFG
+ /// corresponding to the basic blocks on the BlockList. This uses the
+ /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
+ /// and Kennedy, published in Software--Practice and Experience, 2001,
+ /// 4:1-10. Because the CFG subset does not include any edges leading into
+ /// blocks that define the value, the results are not the usual dominator
+ /// tree. The CFG subset has a single pseudo-entry node with edges to a set
+ /// of root nodes for blocks that define the value. The dominators for this
+ /// subset CFG are not the standard dominators but they are adequate for
+ /// placing PHIs within the subset CFG.
+ void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
+ bool Changed;
+ do {
+ Changed = false;
+ // Iterate over the list in reverse order, i.e., forward on CFG edges.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+ BBInfo *NewIDom = 0;
+
+ // Iterate through the block's predecessors.
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BBInfo *Pred = Info->Preds[p];
+
+ // Treat an unreachable predecessor as a definition with 'undef'.
+ if (Pred->BlkNum == 0) {
+ Pred->AvailableVal = Traits::GetUndefVal(Pred->BB, Updater);
+ (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
+ Pred->DefBB = Pred;
+ Pred->BlkNum = PseudoEntry->BlkNum;
+ PseudoEntry->BlkNum++;
+ }
+
+ if (!NewIDom)
+ NewIDom = Pred;
+ else
+ NewIDom = IntersectDominators(NewIDom, Pred);
+ }
+
+ // Check if the IDom value has changed.
+ if (NewIDom && NewIDom != Info->IDom) {
+ Info->IDom = NewIDom;
+ Changed = true;
+ }
+ }
+ } while (Changed);
+ }
+
+ /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
+ /// any blocks containing definitions of the value. If one is found, then
+ /// the successor of Pred is in the dominance frontier for the definition,
+ /// and this function returns true.
+ bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
+ for (; Pred != IDom; Pred = Pred->IDom) {
+ if (Pred->DefBB == Pred)
+ return true;
+ }
+ return false;
+ }
+
+ /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
+ /// of the known definitions. Iteratively add PHIs in the dom frontiers
+ /// until nothing changes. Along the way, keep track of the nearest
+ /// dominating definitions for non-PHI blocks.
+ void FindPHIPlacement(BlockListTy *BlockList) {
+ bool Changed;
+ do {
+ Changed = false;
+ // Iterate over the list in reverse order, i.e., forward on CFG edges.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+
+ // If this block already needs a PHI, there is nothing to do here.
+ if (Info->DefBB == Info)
+ continue;
+
+ // Default to use the same def as the immediate dominator.
+ BBInfo *NewDefBB = Info->IDom->DefBB;
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
+ // Need a PHI here.
+ NewDefBB = Info;
+ break;
+ }
+ }
+
+ // Check if anything changed.
+ if (NewDefBB != Info->DefBB) {
+ Info->DefBB = NewDefBB;
+ Changed = true;
+ }
+ }
+ } while (Changed);
+ }
+
+ /// FindAvailableVal - If this block requires a PHI, first check if an
+ /// existing PHI matches the PHI placement and reaching definitions computed
+ /// earlier, and if not, create a new PHI. Visit all the block's
+ /// predecessors to calculate the available value for each one and fill in
+ /// the incoming values for a new PHI.
+ void FindAvailableVals(BlockListTy *BlockList) {
+ // Go through the worklist in forward order (i.e., backward through the CFG)
+ // and check if existing PHIs can be used. If not, create empty PHIs where
+ // they are needed.
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I) {
+ BBInfo *Info = *I;
+ // Check if there needs to be a PHI in BB.
+ if (Info->DefBB != Info)
+ continue;
+
+ // Look for an existing PHI.
+ FindExistingPHI(Info->BB, BlockList);
+ if (Info->AvailableVal)
+ continue;
+
+ ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
+ Info->AvailableVal = PHI;
+ (*AvailableVals)[Info->BB] = PHI;
+ }
+
+ // Now go back through the worklist in reverse order to fill in the
+ // arguments for any new PHIs added in the forward traversal.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+
+ if (Info->DefBB != Info) {
+ // Record the available value at join nodes to speed up subsequent
+ // uses of this SSAUpdater for the same value.
+ if (Info->NumPreds > 1)
+ (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
+ continue;
+ }
+
+ // Check if this block contains a newly added PHI.
+ PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
+ if (!PHI)
+ continue;
+
+ // Iterate through the block's predecessors.
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BBInfo *PredInfo = Info->Preds[p];
+ BlkT *Pred = PredInfo->BB;
+ // Skip to the nearest preceding definition.
+ if (PredInfo->DefBB != PredInfo)
+ PredInfo = PredInfo->DefBB;
+ Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
+ }
+
+ DEBUG(dbgs() << " Inserted PHI: " << *PHI << "\n");
+
+ // If the client wants to know about all new instructions, tell it.
+ if (InsertedPHIs) InsertedPHIs->push_back(PHI);
+ }
+ }
+
+ /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
+ /// them match what is needed.
+ void FindExistingPHI(BlkT *BB, BlockListTy *BlockList) {
+ for (typename BlkT::iterator BBI = BB->begin(), BBE = BB->end();
+ BBI != BBE; ++BBI) {
+ PhiT *SomePHI = Traits::InstrIsPHI(BBI);
+ if (!SomePHI)
+ break;
+ if (CheckIfPHIMatches(SomePHI)) {
+ RecordMatchingPHI(SomePHI);
+ break;
+ }
+ // Match failed: clear all the PHITag values.
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I)
+ (*I)->PHITag = 0;
+ }
+ }
+
+ /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
+ /// in the BBMap.
+ bool CheckIfPHIMatches(PhiT *PHI) {
+ SmallVector<PhiT*, 20> WorkList;
+ WorkList.push_back(PHI);
+
+ // Mark that the block containing this PHI has been visited.
+ BBMap[PHI->getParent()]->PHITag = PHI;
+
+ while (!WorkList.empty()) {
+ PHI = WorkList.pop_back_val();
+
+ // Iterate through the PHI's incoming values.
+ for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
+ E = Traits::PHI_end(PHI); I != E; ++I) {
+ ValT IncomingVal = I.getIncomingValue();
+ BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
+ // Skip to the nearest preceding definition.
+ if (PredInfo->DefBB != PredInfo)
+ PredInfo = PredInfo->DefBB;
+
+ // Check if it matches the expected value.
+ if (PredInfo->AvailableVal) {
+ if (IncomingVal == PredInfo->AvailableVal)
+ continue;
+ return false;
+ }
+
+ // Check if the value is a PHI in the correct block.
+ PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
+ if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
+ return false;
+
+ // If this block has already been visited, check if this PHI matches.
+ if (PredInfo->PHITag) {
+ if (IncomingPHIVal == PredInfo->PHITag)
+ continue;
+ return false;
+ }
+ PredInfo->PHITag = IncomingPHIVal;
+
+ WorkList.push_back(IncomingPHIVal);
+ }
+ }
+ return true;
+ }
+
+ /// RecordMatchingPHI - For a PHI node that matches, record it and its input
+ /// PHIs in both the BBMap and the AvailableVals mapping.
+ void RecordMatchingPHI(PhiT *PHI) {
+ SmallVector<PhiT*, 20> WorkList;
+ WorkList.push_back(PHI);
+
+ // Record this PHI.
+ BlkT *BB = PHI->getParent();
+ ValT PHIVal = Traits::GetPHIValue(PHI);
+ (*AvailableVals)[BB] = PHIVal;
+ BBMap[BB]->AvailableVal = PHIVal;
+
+ while (!WorkList.empty()) {
+ PHI = WorkList.pop_back_val();
+
+ // Iterate through the PHI's incoming values.
+ for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
+ E = Traits::PHI_end(PHI); I != E; ++I) {
+ ValT IncomingVal = I.getIncomingValue();
+ PhiT *IncomingPHI = Traits::ValueIsPHI(IncomingVal, Updater);
+ if (!IncomingPHI) continue;
+ BB = IncomingPHI->getParent();
+ BBInfo *Info = BBMap[BB];
+ if (!Info || Info->AvailableVal)
+ continue;
+
+ // Record the PHI and add it to the worklist.
+ (*AvailableVals)[BB] = IncomingVal;
+ Info->AvailableVal = IncomingVal;
+ WorkList.push_back(IncomingPHI);
+ }
+ }
+ }
+};
+
+} // End llvm namespace
+
+#endif
OpenPOWER on IntegriCloud