aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/IR/Function.cpp
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
downloadsrc-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.tar.gz
src-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.zip
Vendor import of llvm trunk r300422:vendor/llvm/llvm-trunk-r300422
Notes
Notes: svn path=/vendor/llvm/dist/; revision=317017 svn path=/vendor/llvm/llvm-trunk-r300422/; revision=317018; tag=vendor/llvm/llvm-trunk-r300422
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r--lib/IR/Function.cpp225
1 files changed, 101 insertions, 124 deletions
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 05419aa3d2bb..c4bb9e83acd7 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -30,7 +30,6 @@ 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>;
//===----------------------------------------------------------------------===//
@@ -39,12 +38,8 @@ template class llvm::SymbolTableListTraits<BasicBlock>;
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 +47,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 +57,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,9 +77,9 @@ 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 {
@@ -129,116 +100,74 @@ uint64_t Argument::getDereferenceableOrNullBytes() const {
return getParent()->getDereferenceableOrNullBytes(getArgNo()+1);
}
-/// 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);
}
-/// addAttr - Add attributes to an argument.
-void Argument::addAttr(AttributeSet AS) {
+void Argument::addAttr(AttributeList 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));
+ getParent()->addAttributes(
+ getArgNo() + 1,
+ AttributeList::get(Parent->getContext(), getArgNo() + 1, B));
}
-/// removeAttr - Remove attributes from an argument.
-void Argument::removeAttr(AttributeSet AS) {
+void Argument::removeAttr(AttributeList 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));
+ getParent()->removeAttributes(
+ getArgNo() + 1,
+ AttributeList::get(Parent->getContext(), getArgNo() + 1, B));
}
-/// 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 +183,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),
+ Arguments(nullptr), NumArgs(Ty->getNumParams()) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
@@ -282,7 +212,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 +221,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 +255,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 +267,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,49 +318,49 @@ 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, AttributeList Attrs) {
+ AttributeList PAL = getAttributes();
PAL = PAL.addAttributes(getContext(), i, 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, AttributeList Attrs) {
+ AttributeList PAL = getAttributes();
PAL = PAL.removeAttributes(getContext(), i, 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::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
- AttributeSet PAL = getAttributes();
+ AttributeList PAL = getAttributes();
PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
@@ -533,10 +489,18 @@ static std::string getMangledTypeStr(Type* Ty) {
} else if (ArrayType* ATyp = dyn_cast<ArrayType>(Ty)) {
Result += "a" + llvm::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));
@@ -1279,9 +1243,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 +1263,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,