diff options
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r-- | lib/IR/Function.cpp | 122 |
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; +} |