summaryrefslogtreecommitdiff
path: root/include/llvm/IR/Function.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/IR/Function.h
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
Notes
Diffstat (limited to 'include/llvm/IR/Function.h')
-rw-r--r--include/llvm/IR/Function.h152
1 files changed, 73 insertions, 79 deletions
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 4f64caeade20a..d7d27e7585c1c 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -19,7 +19,6 @@
#define LLVM_IR_FUNCTION_H
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -30,6 +29,7 @@
namespace llvm {
+template <typename T> class Optional;
class FunctionType;
class LLVMContext;
class DISubprogram;
@@ -56,7 +56,6 @@ private:
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
AttributeSet AttributeSets; ///< Parameter attributes
- FunctionType *Ty;
/*
* Value::SubclassData
@@ -73,13 +72,8 @@ private:
/// Bits from GlobalObject::GlobalObjectSubclassData.
enum {
/// Whether this function is materializable.
- IsMaterializableBit = 1 << 0,
- HasMetadataHashEntryBit = 1 << 1
+ IsMaterializableBit = 0,
};
- void setGlobalObjectBit(unsigned Mask, bool Value) {
- setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
- (Value ? Mask : 0u));
- }
friend class SymbolTableListTraits<Function>;
@@ -89,9 +83,12 @@ private:
/// built on demand, so that the list isn't allocated until the first client
/// needs it. The hasLazyArguments predicate returns true if the arg list
/// hasn't been set up yet.
+public:
bool hasLazyArguments() const {
return getSubclassDataFromValue() & (1<<0);
}
+
+private:
void CheckLazyArguments() const {
if (hasLazyArguments())
BuildLazyArguments();
@@ -166,7 +163,7 @@ public:
AttributeSet getAttributes() const { return AttributeSets; }
/// @brief Set the attribute list for this Function.
- void setAttributes(AttributeSet attrs) { AttributeSets = attrs; }
+ void setAttributes(AttributeSet Attrs) { AttributeSets = Attrs; }
/// @brief Add function attributes to this function.
void addFnAttr(Attribute::AttrKind N) {
@@ -175,9 +172,9 @@ public:
}
/// @brief Remove function attributes from this function.
- void removeFnAttr(Attribute::AttrKind N) {
+ void removeFnAttr(Attribute::AttrKind Kind) {
setAttributes(AttributeSets.removeAttribute(
- getContext(), AttributeSet::FunctionIndex, N));
+ getContext(), AttributeSet::FunctionIndex, Kind));
}
/// @brief Add function attributes to this function.
@@ -200,7 +197,7 @@ public:
/// @brief Return true if the function has the attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
+ return AttributeSets.hasFnAttribute(Kind);
}
bool hasFnAttribute(StringRef Kind) const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
@@ -208,14 +205,16 @@ public:
/// @brief Return the attribute for the given attribute kind.
Attribute getFnAttribute(Attribute::AttrKind Kind) const {
- return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+ return getAttribute(AttributeSet::FunctionIndex, Kind);
}
Attribute getFnAttribute(StringRef Kind) const {
- return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+ return getAttribute(AttributeSet::FunctionIndex, Kind);
}
/// \brief Return the stack alignment for the function.
unsigned getFnStackAlignment() const {
+ if (!hasFnAttribute(Attribute::StackAlignment))
+ return 0;
return AttributeSets.getStackAlignment(AttributeSet::FunctionIndex);
}
@@ -225,17 +224,39 @@ public:
return getSubclassDataFromValue() & (1<<14);
}
const std::string &getGC() const;
- void setGC(const std::string Str);
+ void setGC(std::string Str);
void clearGC();
/// @brief adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attribute::AttrKind attr);
+ void addAttribute(unsigned i, Attribute::AttrKind Kind);
+
+ /// @brief adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attribute Attr);
/// @brief adds the attributes to the list of attributes.
- void addAttributes(unsigned i, AttributeSet attrs);
+ void addAttributes(unsigned i, AttributeSet Attrs);
+
+ /// @brief removes the attribute from the list of attributes.
+ void removeAttribute(unsigned i, Attribute::AttrKind Kind);
+
+ /// @brief removes the attribute from the list of attributes.
+ void removeAttribute(unsigned i, StringRef Kind);
/// @brief removes the attributes from the list of attributes.
- void removeAttributes(unsigned i, AttributeSet attr);
+ void removeAttributes(unsigned i, AttributeSet Attrs);
+
+ /// @brief check if an attributes is in the list of attributes.
+ bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const {
+ return getAttributes().hasAttribute(i, Kind);
+ }
+
+ Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
+ return AttributeSets.getAttribute(i, Kind);
+ }
+
+ Attribute getAttribute(unsigned i, StringRef Kind) const {
+ return AttributeSets.getAttribute(i, Kind);
+ }
/// @brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@@ -263,8 +284,7 @@ public:
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ReadNone);
+ return hasFnAttribute(Attribute::ReadNone);
}
void setDoesNotAccessMemory() {
addFnAttr(Attribute::ReadNone);
@@ -272,27 +292,31 @@ public:
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() ||
- AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ReadOnly);
+ return doesNotAccessMemory() || hasFnAttribute(Attribute::ReadOnly);
}
void setOnlyReadsMemory() {
addFnAttr(Attribute::ReadOnly);
}
+ /// @brief Determine if the function does not access or only writes memory.
+ bool doesNotReadMemory() const {
+ return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly);
+ }
+ void setDoesNotReadMemory() {
+ addFnAttr(Attribute::WriteOnly);
+ }
+
/// @brief Determine if the call can access memmory only using pointers based
/// on its arguments.
bool onlyAccessesArgMemory() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ArgMemOnly);
+ return hasFnAttribute(Attribute::ArgMemOnly);
}
void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); }
/// @brief Determine if the function may only access memory that is
/// inaccessible from the IR.
bool onlyAccessesInaccessibleMemory() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::InaccessibleMemOnly);
+ return hasFnAttribute(Attribute::InaccessibleMemOnly);
}
void setOnlyAccessesInaccessibleMemory() {
addFnAttr(Attribute::InaccessibleMemOnly);
@@ -301,8 +325,7 @@ public:
/// @brief Determine if the function may only access memory that is
// either inaccessible from the IR or pointed to by its arguments.
bool onlyAccessesInaccessibleMemOrArgMem() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::InaccessibleMemOrArgMemOnly);
+ return hasFnAttribute(Attribute::InaccessibleMemOrArgMemOnly);
}
void setOnlyAccessesInaccessibleMemOrArgMem() {
addFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
@@ -310,8 +333,7 @@ public:
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::NoReturn);
+ return hasFnAttribute(Attribute::NoReturn);
}
void setDoesNotReturn() {
addFnAttr(Attribute::NoReturn);
@@ -319,8 +341,7 @@ public:
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::NoUnwind);
+ return hasFnAttribute(Attribute::NoUnwind);
}
void setDoesNotThrow() {
addFnAttr(Attribute::NoUnwind);
@@ -328,8 +349,7 @@ public:
/// @brief Determine if the call cannot be duplicated.
bool cannotDuplicate() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::NoDuplicate);
+ return hasFnAttribute(Attribute::NoDuplicate);
}
void setCannotDuplicate() {
addFnAttr(Attribute::NoDuplicate);
@@ -337,18 +357,19 @@ public:
/// @brief Determine if the call is convergent.
bool isConvergent() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::Convergent);
+ return hasFnAttribute(Attribute::Convergent);
}
void setConvergent() {
addFnAttr(Attribute::Convergent);
}
+ void setNotConvergent() {
+ removeFnAttr(Attribute::Convergent);
+ }
/// Determine if the function is known not to recurse, directly or
/// indirectly.
bool doesNotRecurse() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::NoRecurse);
+ return hasFnAttribute(Attribute::NoRecurse);
}
void setDoesNotRecurse() {
addFnAttr(Attribute::NoRecurse);
@@ -357,8 +378,7 @@ public:
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
- return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::UWTable);
+ return hasFnAttribute(Attribute::UWTable);
}
void setHasUWTable() {
addFnAttr(Attribute::UWTable);
@@ -440,6 +460,12 @@ public:
///
void eraseFromParent() override;
+ /// Steal arguments from another function.
+ ///
+ /// Drop this function's arguments and splice in the ones from \c Src.
+ /// Requires that this has no function body.
+ void stealArgumentListFrom(Function &Src);
+
/// Get the underlying elements of the Function... the basic block list is
/// empty for external functions.
///
@@ -547,6 +573,12 @@ public:
Constant *getPrologueData() const;
void setPrologueData(Constant *PrologueData);
+ /// Print the function to an output stream with an optional
+ /// AssemblyAnnotationWriter.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr,
+ bool ShouldPreserveUseListOrder = false,
+ bool IsForDebug = false) const;
+
/// viewCFG - This function is meant for use from the debugger. You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function with the code for each
@@ -597,35 +629,6 @@ public:
/// setjmp or other function that gcc recognizes as "returning twice".
bool callsFunctionThatReturnsTwice() const;
- /// \brief Check if this has any metadata.
- bool hasMetadata() const { return hasMetadataHashEntry(); }
-
- /// \brief Get the current metadata attachment, if any.
- ///
- /// Returns \c nullptr if such an attachment is missing.
- /// @{
- MDNode *getMetadata(unsigned KindID) const;
- MDNode *getMetadata(StringRef Kind) const;
- /// @}
-
- /// \brief Set a particular kind of metadata attachment.
- ///
- /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
- /// replacing it if it already exists.
- /// @{
- void setMetadata(unsigned KindID, MDNode *MD);
- void setMetadata(StringRef Kind, MDNode *MD);
- /// @}
-
- /// \brief Get all current metadata attachments.
- void
- getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
-
- /// \brief Drop metadata not in the given list.
- ///
- /// Drop all metadata from \c this not included in \c KnownIDs.
- void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
-
/// \brief Set the attached subprogram.
///
/// Calls \a setMetadata() with \a LLVMContext::MD_dbg.
@@ -647,15 +650,6 @@ private:
Value::setValueSubclassData(D);
}
void setValueSubclassDataBit(unsigned Bit, bool On);
-
- bool hasMetadataHashEntry() const {
- return getGlobalObjectSubClassData() & HasMetadataHashEntryBit;
- }
- void setHasMetadataHashEntry(bool HasEntry) {
- setGlobalObjectBit(HasMetadataHashEntryBit, HasEntry);
- }
-
- void clearMetadata();
};
template <>