summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR/Function.cpp')
-rw-r--r--contrib/llvm/lib/IR/Function.cpp410
1 files changed, 230 insertions, 180 deletions
diff --git a/contrib/llvm/lib/IR/Function.cpp b/contrib/llvm/lib/IR/Function.cpp
index 05419aa..85a0198 100644
--- a/contrib/llvm/lib/IR/Function.cpp
+++ b/contrib/llvm/lib/IR/Function.cpp
@@ -1,4 +1,4 @@
-//===-- Function.cpp - Implement the Global object classes ----------------===//
+//===- Function.cpp - Implement the Global object classes -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,37 +14,60 @@
#include "llvm/IR/Function.h"
#include "LLVMContextImpl.h"
#include "SymbolTableListTraitsImpl.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#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"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/SymbolTableListTraits.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <string>
+
using namespace llvm;
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
-template class llvm::SymbolTableListTraits<Argument>;
template class llvm::SymbolTableListTraits<BasicBlock>;
//===----------------------------------------------------------------------===//
// Argument Implementation
//===----------------------------------------------------------------------===//
-void Argument::anchor() { }
-
-Argument::Argument(Type *Ty, const Twine &Name, Function *Par)
- : Value(Ty, Value::ArgumentVal) {
- Parent = nullptr;
-
- if (Par)
- Par->getArgumentList().push_back(this);
+Argument::Argument(Type *Ty, const Twine &Name, Function *Par, unsigned ArgNo)
+ : Value(Ty, Value::ArgumentVal), Parent(Par), ArgNo(ArgNo) {
setName(Name);
}
@@ -52,27 +75,9 @@ void Argument::setParent(Function *parent) {
Parent = parent;
}
-/// getArgNo - Return the index of this formal argument in its containing
-/// function. For example in "void foo(int a, float b)" a is 0 and b is 1.
-unsigned Argument::getArgNo() const {
- const Function *F = getParent();
- assert(F && "Argument is not in a function");
-
- Function::const_arg_iterator AI = F->arg_begin();
- unsigned ArgIdx = 0;
- for (; &*AI != this; ++AI)
- ++ArgIdx;
-
- return ArgIdx;
-}
-
-/// hasNonNullAttr - Return true if this argument has the nonnull attribute on
-/// it in its containing function. Also returns true if at least one byte is
-/// known to be dereferenceable and the pointer is in addrspace(0).
bool Argument::hasNonNullAttr() const {
if (!getType()->isPointerTy()) return false;
- if (getParent()->getAttributes().
- hasAttribute(getArgNo()+1, Attribute::NonNull))
+ if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull))
return true;
else if (getDereferenceableBytes() > 0 &&
getType()->getPointerAddressSpace() == 0)
@@ -80,25 +85,19 @@ bool Argument::hasNonNullAttr() const {
return false;
}
-/// hasByValAttr - Return true if this argument has the byval attribute on it
-/// in its containing function.
bool Argument::hasByValAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::ByVal);
}
bool Argument::hasSwiftSelfAttr() const {
- return getParent()->getAttributes().
- hasAttribute(getArgNo()+1, Attribute::SwiftSelf);
+ return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf);
}
bool Argument::hasSwiftErrorAttr() const {
- return getParent()->getAttributes().
- hasAttribute(getArgNo()+1, Attribute::SwiftError);
+ return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftError);
}
-/// \brief Return true if this argument has the inalloca attribute on it in
-/// its containing function.
bool Argument::hasInAllocaAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::InAlloca);
@@ -106,139 +105,96 @@ bool Argument::hasInAllocaAttr() const {
bool Argument::hasByValOrInAllocaAttr() const {
if (!getType()->isPointerTy()) return false;
- AttributeSet Attrs = getParent()->getAttributes();
- return Attrs.hasAttribute(getArgNo() + 1, Attribute::ByVal) ||
- Attrs.hasAttribute(getArgNo() + 1, Attribute::InAlloca);
+ AttributeList Attrs = getParent()->getAttributes();
+ return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca);
}
unsigned Argument::getParamAlignment() const {
assert(getType()->isPointerTy() && "Only pointers have alignments");
- return getParent()->getParamAlignment(getArgNo()+1);
-
+ return getParent()->getParamAlignment(getArgNo());
}
uint64_t Argument::getDereferenceableBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
- return getParent()->getDereferenceableBytes(getArgNo()+1);
+ return getParent()->getParamDereferenceableBytes(getArgNo());
}
uint64_t Argument::getDereferenceableOrNullBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
- return getParent()->getDereferenceableOrNullBytes(getArgNo()+1);
+ return getParent()->getParamDereferenceableOrNullBytes(getArgNo());
}
-/// hasNestAttr - Return true if this argument has the nest attribute on
-/// it in its containing function.
bool Argument::hasNestAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::Nest);
}
-/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
-/// it in its containing function.
bool Argument::hasNoAliasAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::NoAlias);
}
-/// hasNoCaptureAttr - Return true if this argument has the nocapture attribute
-/// on it in its containing function.
bool Argument::hasNoCaptureAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::NoCapture);
}
-/// hasSRetAttr - Return true if this argument has the sret attribute on
-/// it in its containing function.
bool Argument::hasStructRetAttr() const {
if (!getType()->isPointerTy()) return false;
return hasAttribute(Attribute::StructRet);
}
-/// hasReturnedAttr - Return true if this argument has the returned attribute on
-/// it in its containing function.
bool Argument::hasReturnedAttr() const {
return hasAttribute(Attribute::Returned);
}
-/// hasZExtAttr - Return true if this argument has the zext attribute on it in
-/// its containing function.
bool Argument::hasZExtAttr() const {
return hasAttribute(Attribute::ZExt);
}
-/// hasSExtAttr Return true if this argument has the sext attribute on it in its
-/// containing function.
bool Argument::hasSExtAttr() const {
return hasAttribute(Attribute::SExt);
}
-/// Return true if this argument has the readonly or readnone attribute on it
-/// in its containing function.
bool Argument::onlyReadsMemory() const {
- return getParent()->getAttributes().
- hasAttribute(getArgNo()+1, Attribute::ReadOnly) ||
- getParent()->getAttributes().
- hasAttribute(getArgNo()+1, Attribute::ReadNone);
+ AttributeList Attrs = getParent()->getAttributes();
+ return Attrs.hasParamAttribute(getArgNo(), Attribute::ReadOnly) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::ReadNone);
+}
+
+void Argument::addAttrs(AttrBuilder &B) {
+ AttributeList AL = getParent()->getAttributes();
+ AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B);
+ getParent()->setAttributes(AL);
+}
+
+void Argument::addAttr(Attribute::AttrKind Kind) {
+ getParent()->addParamAttr(getArgNo(), Kind);
}
-/// addAttr - Add attributes to an argument.
-void Argument::addAttr(AttributeSet AS) {
- assert(AS.getNumSlots() <= 1 &&
- "Trying to add more than one attribute set to an argument!");
- AttrBuilder B(AS, AS.getSlotIndex(0));
- getParent()->addAttributes(getArgNo() + 1,
- AttributeSet::get(Parent->getContext(),
- getArgNo() + 1, B));
+void Argument::addAttr(Attribute Attr) {
+ getParent()->addParamAttr(getArgNo(), Attr);
}
-/// removeAttr - Remove attributes from an argument.
-void Argument::removeAttr(AttributeSet AS) {
- assert(AS.getNumSlots() <= 1 &&
- "Trying to remove more than one attribute set from an argument!");
- AttrBuilder B(AS, AS.getSlotIndex(0));
- getParent()->removeAttributes(getArgNo() + 1,
- AttributeSet::get(Parent->getContext(),
- getArgNo() + 1, B));
+void Argument::removeAttr(Attribute::AttrKind Kind) {
+ getParent()->removeParamAttr(getArgNo(), Kind);
}
-/// hasAttribute - Checks if an argument has a given attribute.
bool Argument::hasAttribute(Attribute::AttrKind Kind) const {
- return getParent()->hasAttribute(getArgNo() + 1, Kind);
+ return getParent()->hasParamAttribute(getArgNo(), Kind);
}
//===----------------------------------------------------------------------===//
// Helper Methods in Function
//===----------------------------------------------------------------------===//
-bool Function::isMaterializable() const {
- return getGlobalObjectSubClassData() & (1 << IsMaterializableBit);
-}
-
-void Function::setIsMaterializable(bool V) {
- unsigned Mask = 1 << IsMaterializableBit;
- setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
- (V ? Mask : 0u));
-}
-
LLVMContext &Function::getContext() const {
return getType()->getContext();
}
-FunctionType *Function::getFunctionType() const {
- return cast<FunctionType>(getValueType());
-}
-
-bool Function::isVarArg() const {
- return getFunctionType()->isVarArg();
-}
-
-Type *Function::getReturnType() const {
- return getFunctionType()->getReturnType();
-}
-
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
@@ -254,7 +210,8 @@ void Function::eraseFromParent() {
Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
Module *ParentModule)
: GlobalObject(Ty, Value::FunctionVal,
- OperandTraits<Function>::op_begin(this), 0, Linkage, name) {
+ OperandTraits<Function>::op_begin(this), 0, Linkage, name),
+ NumArgs(Ty->getNumParams()) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
@@ -282,7 +239,8 @@ Function::~Function() {
dropAllReferences(); // After this it is safe to delete instructions.
// Delete all of the method arguments and unlink from symbol table...
- ArgumentList.clear();
+ if (Arguments)
+ clearArguments();
// Remove the function from the on-the-side GC table.
clearGC();
@@ -290,16 +248,33 @@ Function::~Function() {
void Function::BuildLazyArguments() const {
// Create the arguments vector, all arguments start out unnamed.
- FunctionType *FT = getFunctionType();
- for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
- assert(!FT->getParamType(i)->isVoidTy() &&
- "Cannot have void typed arguments!");
- ArgumentList.push_back(new Argument(FT->getParamType(i)));
+ auto *FT = getFunctionType();
+ if (NumArgs > 0) {
+ Arguments = std::allocator<Argument>().allocate(NumArgs);
+ for (unsigned i = 0, e = NumArgs; i != e; ++i) {
+ Type *ArgTy = FT->getParamType(i);
+ assert(!ArgTy->isVoidTy() && "Cannot have void typed arguments!");
+ new (Arguments + i) Argument(ArgTy, "", const_cast<Function *>(this), i);
+ }
}
// Clear the lazy arguments bit.
unsigned SDC = getSubclassDataFromValue();
const_cast<Function*>(this)->setValueSubclassData(SDC &= ~(1<<0));
+ assert(!hasLazyArguments());
+}
+
+static MutableArrayRef<Argument> makeArgArray(Argument *Args, size_t Count) {
+ return MutableArrayRef<Argument>(Args, Count);
+}
+
+void Function::clearArguments() {
+ for (Argument &A : makeArgArray(Arguments, NumArgs)) {
+ A.setName("");
+ A.~Argument();
+ }
+ std::allocator<Argument>().deallocate(Arguments, NumArgs);
+ Arguments = nullptr;
}
void Function::stealArgumentListFrom(Function &Src) {
@@ -307,10 +282,10 @@ void Function::stealArgumentListFrom(Function &Src) {
// Drop the current arguments, if any, and set the lazy argument bit.
if (!hasLazyArguments()) {
- assert(llvm::all_of(ArgumentList,
+ assert(llvm::all_of(makeArgArray(Arguments, NumArgs),
[](const Argument &A) { return A.use_empty(); }) &&
"Expected arguments to be unused in declaration");
- ArgumentList.clear();
+ clearArguments();
setValueSubclassData(getSubclassDataFromValue() | (1 << 0));
}
@@ -319,18 +294,26 @@ void Function::stealArgumentListFrom(Function &Src) {
return;
// Steal arguments from Src, and fix the lazy argument bits.
- ArgumentList.splice(ArgumentList.end(), Src.ArgumentList);
+ assert(arg_size() == Src.arg_size());
+ Arguments = Src.Arguments;
+ Src.Arguments = nullptr;
+ for (Argument &A : makeArgArray(Arguments, NumArgs)) {
+ // FIXME: This does the work of transferNodesFromList inefficiently.
+ SmallString<128> Name;
+ if (A.hasName())
+ Name = A.getName();
+ if (!Name.empty())
+ A.setName("");
+ A.setParent(this);
+ if (!Name.empty())
+ A.setName(Name);
+ }
+
setValueSubclassData(getSubclassDataFromValue() & ~(1 << 0));
+ assert(!hasLazyArguments());
Src.setValueSubclassData(Src.getSubclassDataFromValue() | (1 << 0));
}
-size_t Function::arg_size() const {
- return getFunctionType()->getNumParams();
-}
-bool Function::arg_empty() const {
- return getFunctionType()->getNumParams() == 0;
-}
-
// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular
@@ -362,53 +345,102 @@ void Function::dropAllReferences() {
}
void Function::addAttribute(unsigned i, Attribute::AttrKind Kind) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, Kind);
setAttributes(PAL);
}
void Function::addAttribute(unsigned i, Attribute Attr) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, Attr);
setAttributes(PAL);
}
-void Function::addAttributes(unsigned i, AttributeSet Attrs) {
- AttributeSet PAL = getAttributes();
+void Function::addAttributes(unsigned i, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
PAL = PAL.addAttributes(getContext(), i, Attrs);
setAttributes(PAL);
}
+void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::addParamAttr(unsigned ArgNo, Attribute Attr) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Attr);
+ setAttributes(PAL);
+}
+
+void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttributes(getContext(), ArgNo, Attrs);
+ setAttributes(PAL);
+}
+
void Function::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, Kind);
setAttributes(PAL);
}
void Function::removeAttribute(unsigned i, StringRef Kind) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, Kind);
setAttributes(PAL);
}
-void Function::removeAttributes(unsigned i, AttributeSet Attrs) {
- AttributeSet PAL = getAttributes();
+void Function::removeAttributes(unsigned i, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
PAL = PAL.removeAttributes(getContext(), i, Attrs);
setAttributes(PAL);
}
+void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttributes(getContext(), ArgNo, Attrs);
+ setAttributes(PAL);
+}
+
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
+void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addDereferenceableParamAttr(getContext(), ArgNo, Bytes);
+ setAttributes(PAL);
+}
+
void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
+void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,
+ uint64_t Bytes) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullParamAttr(getContext(), ArgNo, Bytes);
+ setAttributes(PAL);
+}
+
const std::string &Function::getGC() const {
assert(hasGC() && "Function has no collector");
return getContext().getGC(*this);
@@ -428,24 +460,20 @@ void Function::clearGC() {
/// Copy all additional attributes (those not needed to create a Function) from
/// the Function Src to this one.
-void Function::copyAttributesFrom(const GlobalValue *Src) {
+void Function::copyAttributesFrom(const Function *Src) {
GlobalObject::copyAttributesFrom(Src);
- const Function *SrcF = dyn_cast<Function>(Src);
- if (!SrcF)
- return;
-
- setCallingConv(SrcF->getCallingConv());
- setAttributes(SrcF->getAttributes());
- if (SrcF->hasGC())
- setGC(SrcF->getGC());
+ setCallingConv(Src->getCallingConv());
+ setAttributes(Src->getAttributes());
+ if (Src->hasGC())
+ setGC(Src->getGC());
else
clearGC();
- if (SrcF->hasPersonalityFn())
- setPersonalityFn(SrcF->getPersonalityFn());
- if (SrcF->hasPrefixData())
- setPrefixData(SrcF->getPrefixData());
- if (SrcF->hasPrologueData())
- setPrologueData(SrcF->getPrologueData());
+ if (Src->hasPersonalityFn())
+ setPersonalityFn(Src->getPersonalityFn());
+ if (Src->hasPrefixData())
+ setPrefixData(Src->getPrefixData());
+ if (Src->hasPrologueData())
+ setPrologueData(Src->getPrologueData());
}
/// Table of string intrinsic names indexed by enum value.
@@ -528,15 +556,23 @@ void Function::recalculateIntrinsicID() {
static std::string getMangledTypeStr(Type* Ty) {
std::string Result;
if (PointerType* PTyp = dyn_cast<PointerType>(Ty)) {
- Result += "p" + llvm::utostr(PTyp->getAddressSpace()) +
+ Result += "p" + utostr(PTyp->getAddressSpace()) +
getMangledTypeStr(PTyp->getElementType());
} else if (ArrayType* ATyp = dyn_cast<ArrayType>(Ty)) {
- Result += "a" + llvm::utostr(ATyp->getNumElements()) +
+ Result += "a" + utostr(ATyp->getNumElements()) +
getMangledTypeStr(ATyp->getElementType());
- } else if (StructType* STyp = dyn_cast<StructType>(Ty)) {
- assert(!STyp->isLiteral() && "TODO: implement literal types");
- Result += STyp->getName();
- } else if (FunctionType* FT = dyn_cast<FunctionType>(Ty)) {
+ } else if (StructType *STyp = dyn_cast<StructType>(Ty)) {
+ if (!STyp->isLiteral()) {
+ Result += "s_";
+ Result += STyp->getName();
+ } else {
+ Result += "sl_";
+ for (auto Elem : STyp->elements())
+ Result += getMangledTypeStr(Elem);
+ }
+ // Ensure nested structs are distinguishable.
+ Result += "s";
+ } else if (FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
Result += "f_" + getMangledTypeStr(FT->getReturnType());
for (size_t i = 0; i < FT->getNumParams(); i++)
Result += getMangledTypeStr(FT->getParamType(i));
@@ -568,7 +604,6 @@ std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
return Result;
}
-
/// IIT_Info - These are enumerators that describe the entries returned by the
/// getIntrinsicInfoTableEntries function.
///
@@ -611,18 +646,18 @@ enum IIT_Info {
IIT_SAME_VEC_WIDTH_ARG = 31,
IIT_PTR_TO_ARG = 32,
IIT_PTR_TO_ELT = 33,
- IIT_VEC_OF_PTRS_TO_ELT = 34,
+ IIT_VEC_OF_ANYPTRS_TO_ELT = 34,
IIT_I128 = 35,
IIT_V512 = 36,
IIT_V1024 = 37
};
-
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
+ using namespace Intrinsic;
+
IIT_Info Info = IIT_Info(Infos[NextElt++]);
unsigned StructElts = 2;
- using namespace Intrinsic;
switch (Info) {
case IIT_Done:
@@ -753,10 +788,11 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
OutputTable.push_back(IITDescriptor::get(IITDescriptor::PtrToElt, ArgInfo));
return;
}
- case IIT_VEC_OF_PTRS_TO_ELT: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfPtrsToElt,
- ArgInfo));
+ case IIT_VEC_OF_ANYPTRS_TO_ELT: {
+ unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(
+ IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
return;
}
case IIT_EMPTYSTRUCT:
@@ -776,7 +812,6 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
llvm_unreachable("unhandled");
}
-
#define GET_INTRINSIC_GENERATOR_GLOBAL
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_GENERATOR_GLOBAL
@@ -814,10 +849,10 @@ void Intrinsic::getIntrinsicInfoTableEntries(ID id,
DecodeIITType(NextElt, IITEntries, T);
}
-
static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
ArrayRef<Type*> Tys, LLVMContext &Context) {
using namespace Intrinsic;
+
IITDescriptor D = Infos.front();
Infos = Infos.slice(1);
@@ -845,7 +880,6 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
Elts[i] = DecodeFixedType(Infos, Tys, Context);
return StructType::get(Context, makeArrayRef(Elts,D.Struct_NumElements));
}
-
case IITDescriptor::Argument:
return Tys[D.getArgumentNumber()];
case IITDescriptor::ExtendArgument: {
@@ -887,21 +921,13 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
Type *EltTy = VTy->getVectorElementType();
return PointerType::getUnqual(EltTy);
}
- case IITDescriptor::VecOfPtrsToElt: {
- Type *Ty = Tys[D.getArgumentNumber()];
- VectorType *VTy = dyn_cast<VectorType>(Ty);
- if (!VTy)
- llvm_unreachable("Expected an argument of Vector Type");
- Type *EltTy = VTy->getVectorElementType();
- return VectorType::get(PointerType::getUnqual(EltTy),
- VTy->getNumElements());
+ case IITDescriptor::VecOfAnyPtrsToElt:
+ // Return the overloaded type (which determines the pointers address space)
+ return Tys[D.getOverloadArgNumber()];
}
- }
llvm_unreachable("unhandled");
}
-
-
FunctionType *Intrinsic::getType(LLVMContext &Context,
ID id, ArrayRef<Type*> Tys) {
SmallVector<IITDescriptor, 8> Table;
@@ -1091,11 +1117,22 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor>
return (!ThisArgType || !ReferenceType ||
ThisArgType->getElementType() != ReferenceType->getElementType());
}
- case IITDescriptor::VecOfPtrsToElt: {
- if (D.getArgumentNumber() >= ArgTys.size())
+ case IITDescriptor::VecOfAnyPtrsToElt: {
+ unsigned RefArgNumber = D.getRefArgNumber();
+
+ // This may only be used when referring to a previous argument.
+ if (RefArgNumber >= ArgTys.size())
return true;
- VectorType * ReferenceType =
- dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]);
+
+ // Record the overloaded type
+ assert(D.getOverloadArgNumber() == ArgTys.size() &&
+ "Table consistency error");
+ ArgTys.push_back(Ty);
+
+ // Verify the overloaded type "matches" the Ref type.
+ // i.e. Ty is a vector with the same width as Ref.
+ // Composed of pointers to the same element type as Ref.
+ VectorType *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
(ReferenceType->getVectorNumElements() !=
@@ -1279,9 +1316,10 @@ void Function::setValueSubclassDataBit(unsigned Bit, bool On) {
setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));
}
-void Function::setEntryCount(uint64_t Count) {
+void Function::setEntryCount(uint64_t Count,
+ const DenseSet<GlobalValue::GUID> *S) {
MDBuilder MDB(getContext());
- setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(Count));
+ setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(Count, S));
}
Optional<uint64_t> Function::getEntryCount() const {
@@ -1298,6 +1336,18 @@ Optional<uint64_t> Function::getEntryCount() const {
return None;
}
+DenseSet<GlobalValue::GUID> Function::getImportGUIDs() const {
+ DenseSet<GlobalValue::GUID> R;
+ if (MDNode *MD = getMetadata(LLVMContext::MD_prof))
+ if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0)))
+ if (MDS->getString().equals("function_entry_count"))
+ for (unsigned i = 2; i < MD->getNumOperands(); i++)
+ R.insert(mdconst::extract<ConstantInt>(MD->getOperand(i))
+ ->getValue()
+ .getZExtValue());
+ return R;
+}
+
void Function::setSectionPrefix(StringRef Prefix) {
MDBuilder MDB(getContext());
setMetadata(LLVMContext::MD_section_prefix,
OpenPOWER on IntegriCloud