summaryrefslogtreecommitdiff
path: root/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r--lib/IR/Function.cpp122
1 files changed, 92 insertions, 30 deletions
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 7063f6f40a30..aba329b80508 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -21,7 +21,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -56,6 +55,7 @@
#include <string>
using namespace llvm;
+using ProfileCount = Function::ProfileCount;
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
@@ -79,7 +79,8 @@ bool Argument::hasNonNullAttr() const {
if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull))
return true;
else if (getDereferenceableBytes() > 0 &&
- getType()->getPointerAddressSpace() == 0)
+ !NullPointerIsDefined(getParent(),
+ getType()->getPointerAddressSpace()))
return true;
return false;
}
@@ -194,6 +195,14 @@ LLVMContext &Function::getContext() const {
return getType()->getContext();
}
+unsigned Function::getInstructionCount() {
+ unsigned NumInstrs = 0;
+ for (BasicBlock &BB : BasicBlocks)
+ NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),
+ BB.instructionsWithoutDebug().end());
+ return NumInstrs;
+}
+
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
@@ -479,13 +488,13 @@ void Function::copyAttributesFrom(const Function *Src) {
static const char * const IntrinsicNameTable[] = {
"not_intrinsic",
#define GET_INTRINSIC_NAME_TABLE
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_NAME_TABLE
};
/// Table of per-target intrinsic name tables.
#define GET_INTRINSIC_TARGET_DATA
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_TARGET_DATA
/// Find the segment of \c IntrinsicNameTable for intrinsics with the same
@@ -508,7 +517,7 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
return makeArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
}
-/// \brief This does the actual lookup of an intrinsic ID which
+/// This does the actual lookup of an intrinsic ID which
/// matches the given function name.
Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
ArrayRef<const char *> NameTable = findTargetSubtable(Name);
@@ -522,9 +531,11 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + Adjust);
// If the intrinsic is not overloaded, require an exact match. If it is
- // overloaded, require a prefix match.
- bool IsPrefixMatch = Name.size() > strlen(NameTable[Idx]);
- return IsPrefixMatch == isOverloaded(ID) ? ID : Intrinsic::not_intrinsic;
+ // overloaded, require either exact or prefix match.
+ const auto MatchSize = strlen(NameTable[Idx]);
+ assert(Name.size() >= MatchSize && "Expected either exact or prefix match");
+ bool IsExactMatch = Name.size() == MatchSize;
+ return IsExactMatch || isOverloaded(ID) ? ID : Intrinsic::not_intrinsic;
}
void Function::recalculateIntrinsicID() {
@@ -548,10 +559,7 @@ void Function::recalculateIntrinsicID() {
/// which can't be confused with it's prefix. This ensures we don't have
/// collisions between two unrelated function types. Otherwise, you might
/// parse ffXX as f(fXX) or f(fX)X. (X is a placeholder for any other type.)
-/// Manglings of integers, floats, and vectors ('i', 'f', and 'v' prefix in most
-/// cases) fall back to the MVT codepath, where they could be mangled to
-/// 'x86mmx', for example; matching on derived types is not sufficient to mangle
-/// everything.
+///
static std::string getMangledTypeStr(Type* Ty) {
std::string Result;
if (PointerType* PTyp = dyn_cast<PointerType>(Ty)) {
@@ -579,11 +587,26 @@ static std::string getMangledTypeStr(Type* Ty) {
Result += "vararg";
// Ensure nested function types are distinguishable.
Result += "f";
- } else if (isa<VectorType>(Ty))
+ } else if (isa<VectorType>(Ty)) {
Result += "v" + utostr(Ty->getVectorNumElements()) +
getMangledTypeStr(Ty->getVectorElementType());
- else if (Ty)
- Result += EVT::getEVT(Ty).getEVTString();
+ } else if (Ty) {
+ switch (Ty->getTypeID()) {
+ default: llvm_unreachable("Unhandled type");
+ case Type::VoidTyID: Result += "isVoid"; break;
+ case Type::MetadataTyID: Result += "Metadata"; break;
+ case Type::HalfTyID: Result += "f16"; break;
+ case Type::FloatTyID: Result += "f32"; break;
+ case Type::DoubleTyID: Result += "f64"; break;
+ case Type::X86_FP80TyID: Result += "f80"; break;
+ case Type::FP128TyID: Result += "f128"; break;
+ case Type::PPC_FP128TyID: Result += "ppcf128"; break;
+ case Type::X86_MMXTyID: Result += "x86mmx"; break;
+ case Type::IntegerTyID:
+ Result += "i" + utostr(cast<IntegerType>(Ty)->getBitWidth());
+ break;
+ }
+ }
return Result;
}
@@ -651,7 +674,8 @@ enum IIT_Info {
IIT_V1024 = 37,
IIT_STRUCT6 = 38,
IIT_STRUCT7 = 39,
- IIT_STRUCT8 = 40
+ IIT_STRUCT8 = 40,
+ IIT_F128 = 41
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -686,6 +710,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_F64:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));
return;
+ case IIT_F128:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0));
+ return;
case IIT_I1:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
return;
@@ -818,7 +845,7 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
}
#define GET_INTRINSIC_GENERATOR_GLOBAL
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_GENERATOR_GLOBAL
void Intrinsic::getIntrinsicInfoTableEntries(ID id,
@@ -870,6 +897,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Half: return Type::getHalfTy(Context);
case IITDescriptor::Float: return Type::getFloatTy(Context);
case IITDescriptor::Double: return Type::getDoubleTy(Context);
+ case IITDescriptor::Quad: return Type::getFP128Ty(Context);
case IITDescriptor::Integer:
return IntegerType::get(Context, D.Integer_Width);
@@ -955,7 +983,7 @@ FunctionType *Intrinsic::getType(LLVMContext &Context,
bool Intrinsic::isOverloaded(ID id) {
#define GET_INTRINSIC_OVERLOAD_TABLE
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_OVERLOAD_TABLE
}
@@ -973,7 +1001,7 @@ bool Intrinsic::isLeaf(ID id) {
/// This defines the "Intrinsic::getAttributes(ID id)" method.
#define GET_INTRINSIC_ATTRIBUTES
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_ATTRIBUTES
Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
@@ -986,12 +1014,12 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
// This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method.
#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
// This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method.
#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
-#include "llvm/IR/Intrinsics.gen"
+#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
@@ -1012,6 +1040,7 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor>
case IITDescriptor::Half: return !Ty->isHalfTy();
case IITDescriptor::Float: return !Ty->isFloatTy();
case IITDescriptor::Double: return !Ty->isDoubleTy();
+ case IITDescriptor::Quad: return !Ty->isFP128Ty();
case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width);
case IITDescriptor::Vector: {
VectorType *VT = dyn_cast<VectorType>(Ty);
@@ -1320,26 +1349,43 @@ void Function::setValueSubclassDataBit(unsigned Bit, bool On) {
setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));
}
-void Function::setEntryCount(uint64_t Count,
+void Function::setEntryCount(ProfileCount Count,
const DenseSet<GlobalValue::GUID> *S) {
+ assert(Count.hasValue());
+#if !defined(NDEBUG)
+ auto PrevCount = getEntryCount();
+ assert(!PrevCount.hasValue() || PrevCount.getType() == Count.getType());
+#endif
MDBuilder MDB(getContext());
- setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(Count, S));
+ setMetadata(
+ LLVMContext::MD_prof,
+ MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S));
}
-Optional<uint64_t> Function::getEntryCount() const {
+void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,
+ const DenseSet<GlobalValue::GUID> *Imports) {
+ setEntryCount(ProfileCount(Count, Type), Imports);
+}
+
+ProfileCount Function::getEntryCount() const {
MDNode *MD = getMetadata(LLVMContext::MD_prof);
if (MD && MD->getOperand(0))
- if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0)))
+ if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
if (MDS->getString().equals("function_entry_count")) {
ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
uint64_t Count = CI->getValue().getZExtValue();
// A value of -1 is used for SamplePGO when there were no samples.
// Treat this the same as unknown.
if (Count == (uint64_t)-1)
- return None;
- return Count;
+ return ProfileCount::getInvalid();
+ return ProfileCount(Count, PCT_Real);
+ } else if (MDS->getString().equals("synthetic_function_entry_count")) {
+ ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
+ uint64_t Count = CI->getValue().getZExtValue();
+ return ProfileCount(Count, PCT_Synthetic);
}
- return None;
+ }
+ return ProfileCount::getInvalid();
}
DenseSet<GlobalValue::GUID> Function::getImportGUIDs() const {
@@ -1362,11 +1408,27 @@ void Function::setSectionPrefix(StringRef Prefix) {
Optional<StringRef> Function::getSectionPrefix() const {
if (MDNode *MD = getMetadata(LLVMContext::MD_section_prefix)) {
- assert(dyn_cast<MDString>(MD->getOperand(0))
+ assert(cast<MDString>(MD->getOperand(0))
->getString()
.equals("function_section_prefix") &&
"Metadata not match");
- return dyn_cast<MDString>(MD->getOperand(1))->getString();
+ return cast<MDString>(MD->getOperand(1))->getString();
}
return None;
}
+
+bool Function::nullPointerIsDefined() const {
+ return getFnAttribute("null-pointer-is-valid")
+ .getValueAsString()
+ .equals("true");
+}
+
+bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) {
+ if (F && F->nullPointerIsDefined())
+ return true;
+
+ if (AS != 0)
+ return true;
+
+ return false;
+}