#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"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/OperandTraits.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
class FunctionType;
class LLVMContext;
+class DISubprogram;
-template<> struct ilist_traits<Argument>
- : public SymbolTableListTraits<Argument, Function> {
-
- Argument *createSentinel() const {
- return static_cast<Argument*>(&Sentinel);
- }
- static void destroySentinel(Argument*) {}
-
- Argument *provideInitialHead() const { return createSentinel(); }
- Argument *ensureHead(Argument*) const { return createSentinel(); }
- static void noteHead(Argument*, Argument*) {}
-
- static ValueSymbolTable *getSymTab(Function *ItemParent);
-private:
- mutable ilist_half_node<Argument> Sentinel;
-};
+template <>
+struct SymbolTableListSentinelTraits<Argument>
+ : public ilist_half_embedded_sentinel_traits<Argument> {};
class Function : public GlobalObject, public ilist_node<Function> {
public:
- typedef iplist<Argument> ArgumentListType;
- typedef iplist<BasicBlock> BasicBlockListType;
+ typedef SymbolTableList<Argument> ArgumentListType;
+ typedef SymbolTableList<BasicBlock> BasicBlockListType;
// BasicBlock iterators...
typedef BasicBlockListType::iterator iterator;
/*
* Value::SubclassData
*
- * bit 0 : HasLazyArguments
- * bit 1 : HasPrefixData
- * bit 2 : HasPrologueData
- * bit 3-6: CallingConvention
+ * bit 0 : HasLazyArguments
+ * bit 1 : HasPrefixData
+ * bit 2 : HasPrologueData
+ * bit 3 : [reserved]
+ * bits 4-13 : CallingConvention
+ * bits 14-15 : [reserved]
*/
/// Bits from GlobalObject::GlobalObjectSubclassData.
(Value ? Mask : 0u));
}
- friend class SymbolTableListTraits<Function, Module>;
+ friend class SymbolTableListTraits<Function>;
void setParent(Module *parent);
Function(const Function&) = delete;
void operator=(const Function&) = delete;
- /// Do the actual lookup of an intrinsic ID when the query could not be
- /// answered from the cache.
- unsigned lookupIntrinsicID() const LLVM_READONLY;
-
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
/// the module.
public:
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = nullptr) {
- return new(0) Function(Ty, Linkage, N, M);
+ return new(1) Function(Ty, Linkage, N, M);
}
~Function() override;
+ /// \brief Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// \brief Get the personality function associated with this function.
+ bool hasPersonalityFn() const { return getNumOperands() != 0; }
+ Constant *getPersonalityFn() const {
+ assert(hasPersonalityFn());
+ return cast<Constant>(Op<0>());
+ }
+ void setPersonalityFn(Constant *C);
+
Type *getReturnType() const; // Return the type of the ret val
FunctionType *getFunctionType() const; // Return the FunctionType for me
- /// getContext - Return a pointer to the LLVMContext associated with this
- /// function, or NULL if this function is not bound to a context yet.
+ /// getContext - Return a reference to the LLVMContext associated with this
+ /// function.
LLVMContext &getContext() const;
/// isVarArg - Return true if this function takes a variable number of
/// intrinsic, or if the pointer is null. This value is always defined to be
/// zero to allow easy checking for whether a function is intrinsic or not.
/// The particular intrinsic functions which correspond to this value are
- /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context,
- /// subsequent requests for the same ID return results much faster from the
- /// cache.
- ///
- unsigned getIntrinsicID() const LLVM_READONLY;
+ /// defined in llvm/Intrinsics.h.
+ Intrinsic::ID getIntrinsicID() const LLVM_READONLY { return IntID; }
bool isIntrinsic() const { return getName().startswith("llvm."); }
+ /// \brief Recalculate the ID for this function if it is an Intrinsic defined
+ /// in llvm/Intrinsics.h. Sets the intrinsic ID to Intrinsic::not_intrinsic
+ /// if the name of this function does not match an intrinsic in that header.
+ /// Note, this method does not need to be called directly, as it is called
+ /// from Value::setName() whenever the name of this function changes.
+ void recalculateIntrinsicID();
+
/// getCallingConv()/setCallingConv(CC) - These method get and set the
/// calling convention of this function. The enum values for the known
/// calling conventions are defined in CallingConv.h.
CallingConv::ID getCallingConv() const {
- return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 3);
+ return static_cast<CallingConv::ID>((getSubclassDataFromValue() >> 4) &
+ CallingConv::MaxID);
}
void setCallingConv(CallingConv::ID CC) {
- setValueSubclassData((getSubclassDataFromValue() & 7) |
- (static_cast<unsigned>(CC) << 3));
+ auto ID = static_cast<unsigned>(CC);
+ assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention");
+ setValueSubclassData((getSubclassDataFromValue() & 0xc00f) | (ID << 4));
}
/// @brief Return the attribute list for this Function.
AttributeSet::FunctionIndex, Kind, Value));
}
+ /// Set the entry count for this function.
+ void setEntryCount(uint64_t Count);
+
+ /// Get the entry count for this function.
+ Optional<uint64_t> getEntryCount() const;
+
/// @brief Return true if the function has the attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
return AttributeSets.getDereferenceableBytes(i);
}
+ /// @brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned i) const {
+ return AttributeSets.getDereferenceableOrNullBytes(i);
+ }
+
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
addFnAttr(Attribute::ReadOnly);
}
+ /// @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);
+ }
+ 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);
+ }
+ void setOnlyAccessesInaccessibleMemory() {
+ addFnAttr(Attribute::InaccessibleMemOnly);
+ }
+
+ /// @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);
+ }
+ void setOnlyAccessesInaccessibleMemOrArgMem() {
+ addFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
+ }
+
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
addFnAttr(Attribute::NoDuplicate);
}
+ /// @brief Determine if the call is convergent.
+ bool isConvergent() const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::Convergent);
+ }
+ void setConvergent() {
+ addFnAttr(Attribute::Convergent);
+ }
+
+ /// Determine if the function is known not to recurse, directly or
+ /// indirectly.
+ bool doesNotRecurse() const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoRecurse);
+ }
+ void setDoesNotRecurse() {
+ addFnAttr(Attribute::NoRecurse);
+ }
+
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
AttributeSets.hasAttribute(2, Attribute::StructRet);
}
- /// @brief Determine if the parameter does not alias other parameters.
+ /// @brief Determine if the parameter or return value is marked with NoAlias
+ /// attribute.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
return AttributeSets.hasAttribute(n, Attribute::NoAlias);
addAttribute(n, Attribute::ReadOnly);
}
+ /// Optimize this function for minimum size (-Oz).
+ bool optForMinSize() const { return hasFnAttribute(Attribute::MinSize); };
+
+ /// Optimize this function for size (-Os) or minimum size (-Oz).
+ bool optForSize() const {
+ return hasFnAttribute(Attribute::OptimizeForSize) || optForMinSize();
+ }
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a Function) from the Function Src to this one.
void copyAttributesFrom(const GlobalValue *Src) override;
///
void eraseFromParent() override;
-
/// Get the underlying elements of the Function... the basic block list is
/// empty for external functions.
///
CheckLazyArguments();
return ArgumentList;
}
- static iplist<Argument> Function::*getSublistAccess(Argument*) {
+ static ArgumentListType Function::*getSublistAccess(Argument*) {
return &Function::ArgumentList;
}
const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
- static iplist<BasicBlock> Function::*getSublistAccess(BasicBlock*) {
+ static BasicBlockListType Function::*getSublistAccess(BasicBlock*) {
return &Function::BasicBlocks;
}
inline ValueSymbolTable &getValueSymbolTable() { return *SymTab; }
inline const ValueSymbolTable &getValueSymbolTable() const { return *SymTab; }
-
//===--------------------------------------------------------------------===//
// BasicBlock iterator forwarding functions
//
}
iterator_range<arg_iterator> args() {
- return iterator_range<arg_iterator>(arg_begin(), arg_end());
+ return make_range(arg_begin(), arg_end());
}
iterator_range<const_arg_iterator> args() const {
- return iterator_range<const_arg_iterator>(arg_begin(), arg_end());
+ return make_range(arg_begin(), arg_end());
}
/// @}
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) 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
/// 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.
+ void setSubprogram(DISubprogram *SP);
+
+ /// \brief Get the attached subprogram.
+ ///
+ /// Calls \a getMetadata() with \a LLVMContext::MD_dbg and casts the result
+ /// to \a DISubprogram.
+ DISubprogram *getSubprogram() const;
+
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.
void clearMetadata();
};
-inline ValueSymbolTable *
-ilist_traits<BasicBlock>::getSymTab(Function *F) {
- return F ? &F->getValueSymbolTable() : nullptr;
-}
+template <>
+struct OperandTraits<Function> : public OptionalOperandTraits<Function> {};
-inline ValueSymbolTable *
-ilist_traits<Argument>::getSymTab(Function *F) {
- return F ? &F->getValueSymbolTable() : nullptr;
-}
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Function, Value)
} // End llvm namespace