#include "llvm/IR/Function.h"
#include "LLVMContextImpl.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/StringPool.h"
#include "llvm/Support/Threading.h"
using namespace llvm;
template class llvm::SymbolTableListTraits<Argument>;
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);
setName(Name);
}
void Argument::setParent(Function *parent) {
Parent = parent;
}
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;
}
bool Argument::hasNonNullAttr() const {
if (!getType()->isPointerTy()) return false;
if (getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::NonNull))
return true;
else if (getDereferenceableBytes() > 0 &&
getType()->getPointerAddressSpace() == 0)
return true;
return false;
}
bool Argument::hasByValAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ByVal);
}
bool Argument::hasSwiftSelfAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::SwiftSelf);
}
bool Argument::hasSwiftErrorAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::SwiftError);
}
bool Argument::hasInAllocaAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::InAlloca);
}
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);
}
unsigned Argument::getParamAlignment() const {
assert(getType()->isPointerTy() && "Only pointers have alignments");
return getParent()->getParamAlignment(getArgNo()+1);
}
uint64_t Argument::getDereferenceableBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
return getParent()->getDereferenceableBytes(getArgNo()+1);
}
uint64_t Argument::getDereferenceableOrNullBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
return getParent()->getDereferenceableOrNullBytes(getArgNo()+1);
}
bool Argument::hasNestAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::Nest);
}
bool Argument::hasNoAliasAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::NoAlias);
}
bool Argument::hasNoCaptureAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::NoCapture);
}
bool Argument::hasStructRetAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::StructRet);
}
bool Argument::hasReturnedAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::Returned);
}
bool Argument::hasZExtAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ZExt);
}
bool Argument::hasSExtAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::SExt);
}
bool Argument::onlyReadsMemory() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ReadOnly) ||
getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ReadNone);
}
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::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));
}
bool Function::isMaterializable() const {
return getGlobalObjectSubClassData() & IsMaterializableBit;
}
void Function::setIsMaterializable(bool V) {
setGlobalObjectBit(IsMaterializableBit, V);
}
LLVMContext &Function::getContext() const {
return getType()->getContext();
}
FunctionType *Function::getFunctionType() const { return Ty; }
bool Function::isVarArg() const {
return getFunctionType()->isVarArg();
}
Type *Function::getReturnType() const {
return getFunctionType()->getReturnType();
}
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
void Function::eraseFromParent() {
getParent()->getFunctionList().erase(getIterator());
}
Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
Module *ParentModule)
: GlobalObject(Ty, Value::FunctionVal,
OperandTraits<Function>::op_begin(this), 0, Linkage, name),
Ty(Ty) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
SymTab = new ValueSymbolTable();
if (Ty->getNumParams())
setValueSubclassData(1);
if (ParentModule)
ParentModule->getFunctionList().push_back(this);
if (IntID)
setAttributes(Intrinsic::getAttributes(getContext(), IntID));
}
Function::~Function() {
dropAllReferences();
ArgumentList.clear();
delete SymTab;
clearGC();
setFunctionNumOperands(1);
}
void Function::BuildLazyArguments() const {
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)));
}
unsigned SDC = getSubclassDataFromValue();
const_cast<Function*>(this)->setValueSubclassData(SDC &= ~(1<<0));
}
size_t Function::arg_size() const {
return getFunctionType()->getNumParams();
}
bool Function::arg_empty() const {
return getFunctionType()->getNumParams() == 0;
}
void Function::setParent(Module *parent) {
Parent = parent;
}
void Function::dropAllReferences() {
setIsMaterializable(false);
for (iterator I = begin(), E = end(); I != E; ++I)
I->dropAllReferences();
while (!BasicBlocks.empty())
BasicBlocks.begin()->eraseFromParent();
setPrefixData(nullptr);
setPrologueData(nullptr);
clearMetadata();
setPersonalityFn(nullptr);
}
void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, attr);
setAttributes(PAL);
}
void Function::addAttributes(unsigned i, AttributeSet attrs) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttributes(getContext(), i, attrs);
setAttributes(PAL);
}
void Function::removeAttributes(unsigned i, AttributeSet attrs) {
AttributeSet PAL = getAttributes();
PAL = PAL.removeAttributes(getContext(), i, attrs);
setAttributes(PAL);
}
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
AttributeSet PAL = getAttributes();
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
AttributeSet PAL = getAttributes();
PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
static DenseMap<const Function*,PooledStringPtr> *GCNames;
static StringPool *GCNamePool;
static ManagedStatic<sys::SmartRWMutex<true> > GCLock;
bool Function::hasGC() const {
sys::SmartScopedReader<true> Reader(*GCLock);
return GCNames && GCNames->count(this);
}
const char *Function::getGC() const {
assert(hasGC() && "Function has no collector");
sys::SmartScopedReader<true> Reader(*GCLock);
return *(*GCNames)[this];
}
void Function::setGC(const char *Str) {
sys::SmartScopedWriter<true> Writer(*GCLock);
if (!GCNamePool)
GCNamePool = new StringPool();
if (!GCNames)
GCNames = new DenseMap<const Function*,PooledStringPtr>();
(*GCNames)[this] = GCNamePool->intern(Str);
}
void Function::clearGC() {
sys::SmartScopedWriter<true> Writer(*GCLock);
if (GCNames) {
GCNames->erase(this);
if (GCNames->empty()) {
delete GCNames;
GCNames = nullptr;
if (GCNamePool->empty()) {
delete GCNamePool;
GCNamePool = nullptr;
}
}
}
}
void Function::copyAttributesFrom(const GlobalValue *Src) {
assert(isa<Function>(Src) && "Expected a Function!");
GlobalObject::copyAttributesFrom(Src);
const Function *SrcF = cast<Function>(Src);
setCallingConv(SrcF->getCallingConv());
setAttributes(SrcF->getAttributes());
if (SrcF->hasGC())
setGC(SrcF->getGC());
else
clearGC();
if (SrcF->hasPrefixData())
setPrefixData(SrcF->getPrefixData());
else
setPrefixData(nullptr);
if (SrcF->hasPrologueData())
setPrologueData(SrcF->getPrologueData());
else
setPrologueData(nullptr);
if (SrcF->hasPersonalityFn())
setPersonalityFn(SrcF->getPersonalityFn());
else
setPersonalityFn(nullptr);
}
static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) {
unsigned Len = ValName->getKeyLength();
const char *Name = ValName->getKeyData();
#define GET_FUNCTION_RECOGNIZER
#include "llvm/IR/Intrinsics.gen"
#undef GET_FUNCTION_RECOGNIZER
return Intrinsic::not_intrinsic;
}
void Function::recalculateIntrinsicID() {
const ValueName *ValName = this->getValueName();
if (!ValName || !isIntrinsic()) {
IntID = Intrinsic::not_intrinsic;
return;
}
IntID = lookupIntrinsicID(ValName);
}
static std::string getMangledTypeStr(Type* Ty) {
std::string Result;
if (PointerType* PTyp = dyn_cast<PointerType>(Ty)) {
Result += "p" + llvm::utostr(PTyp->getAddressSpace()) +
getMangledTypeStr(PTyp->getElementType());
} 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)) {
Result += "f_" + getMangledTypeStr(FT->getReturnType());
for (size_t i = 0; i < FT->getNumParams(); i++)
Result += getMangledTypeStr(FT->getParamType(i));
if (FT->isVarArg())
Result += "vararg";
Result += "f";
} else if (Ty)
Result += EVT::getEVT(Ty).getEVTString();
return Result;
}
std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
assert(id < num_intrinsics && "Invalid intrinsic ID!");
static const char * const Table[] = {
"not_intrinsic",
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_NAME_TABLE
};
if (Tys.empty())
return Table[id];
std::string Result(Table[id]);
for (unsigned i = 0; i < Tys.size(); ++i) {
Result += "." + getMangledTypeStr(Tys[i]);
}
return Result;
}
enum IIT_Info {
IIT_Done = 0,
IIT_I1 = 1,
IIT_I8 = 2,
IIT_I16 = 3,
IIT_I32 = 4,
IIT_I64 = 5,
IIT_F16 = 6,
IIT_F32 = 7,
IIT_F64 = 8,
IIT_V2 = 9,
IIT_V4 = 10,
IIT_V8 = 11,
IIT_V16 = 12,
IIT_V32 = 13,
IIT_PTR = 14,
IIT_ARG = 15,
IIT_V64 = 16,
IIT_MMX = 17,
IIT_TOKEN = 18,
IIT_METADATA = 19,
IIT_EMPTYSTRUCT = 20,
IIT_STRUCT2 = 21,
IIT_STRUCT3 = 22,
IIT_STRUCT4 = 23,
IIT_STRUCT5 = 24,
IIT_EXTEND_ARG = 25,
IIT_TRUNC_ARG = 26,
IIT_ANYPTR = 27,
IIT_V1 = 28,
IIT_VARARG = 29,
IIT_HALF_VEC_ARG = 30,
IIT_SAME_VEC_WIDTH_ARG = 31,
IIT_PTR_TO_ARG = 32,
IIT_VEC_OF_PTRS_TO_ELT = 33,
IIT_I128 = 34
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
IIT_Info Info = IIT_Info(Infos[NextElt++]);
unsigned StructElts = 2;
using namespace Intrinsic;
switch (Info) {
case IIT_Done:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
return;
case IIT_VARARG:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
return;
case IIT_MMX:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
return;
case IIT_TOKEN:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
return;
case IIT_METADATA:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
return;
case IIT_F16:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0));
return;
case IIT_F32:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0));
return;
case IIT_F64:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));
return;
case IIT_I1:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
return;
case IIT_I8:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
return;
case IIT_I16:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer,16));
return;
case IIT_I32:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
return;
case IIT_I64:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
return;
case IIT_I128:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128));
return;
case IIT_V1:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V2:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V4:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 4));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V8:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 8));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V16:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 16));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V32:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 32));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_V64:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 64));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_PTR:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
DecodeIITType(NextElt, Infos, OutputTable);
return;
case IIT_ANYPTR: { OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer,
Infos[NextElt++]));
DecodeIITType(NextElt, Infos, OutputTable);
return;
}
case IIT_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
return;
}
case IIT_EXTEND_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument,
ArgInfo));
return;
}
case IIT_TRUNC_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument,
ArgInfo));
return;
}
case IIT_HALF_VEC_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument,
ArgInfo));
return;
}
case IIT_SAME_VEC_WIDTH_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::SameVecWidthArgument,
ArgInfo));
return;
}
case IIT_PTR_TO_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::PtrToArgument,
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));
return;
}
case IIT_EMPTYSTRUCT:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
return;
case IIT_STRUCT5: ++StructElts; case IIT_STRUCT4: ++StructElts; case IIT_STRUCT3: ++StructElts; case IIT_STRUCT2: {
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct,StructElts));
for (unsigned i = 0; i != StructElts; ++i)
DecodeIITType(NextElt, Infos, OutputTable);
return;
}
}
llvm_unreachable("unhandled");
}
#define GET_INTRINSIC_GENERATOR_GLOBAL
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_GENERATOR_GLOBAL
void Intrinsic::getIntrinsicInfoTableEntries(ID id,
SmallVectorImpl<IITDescriptor> &T){
unsigned TableVal = IIT_Table[id-1];
SmallVector<unsigned char, 8> IITValues;
ArrayRef<unsigned char> IITEntries;
unsigned NextElt = 0;
if ((TableVal >> 31) != 0) {
IITEntries = IIT_LongEncodingTable;
NextElt = (TableVal << 1) >> 1;
} else {
do {
IITValues.push_back(TableVal & 0xF);
TableVal >>= 4;
} while (TableVal);
IITEntries = IITValues;
NextElt = 0;
}
DecodeIITType(NextElt, IITEntries, T);
while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)
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);
switch (D.Kind) {
case IITDescriptor::Void: return Type::getVoidTy(Context);
case IITDescriptor::VarArg: return Type::getVoidTy(Context);
case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
case IITDescriptor::Token: return Type::getTokenTy(Context);
case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
case IITDescriptor::Half: return Type::getHalfTy(Context);
case IITDescriptor::Float: return Type::getFloatTy(Context);
case IITDescriptor::Double: return Type::getDoubleTy(Context);
case IITDescriptor::Integer:
return IntegerType::get(Context, D.Integer_Width);
case IITDescriptor::Vector:
return VectorType::get(DecodeFixedType(Infos, Tys, Context),D.Vector_Width);
case IITDescriptor::Pointer:
return PointerType::get(DecodeFixedType(Infos, Tys, Context),
D.Pointer_AddressSpace);
case IITDescriptor::Struct: {
Type *Elts[5];
assert(D.Struct_NumElements <= 5 && "Can't handle this yet");
for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
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: {
Type *Ty = Tys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
return VectorType::getExtendedElementVectorType(VTy);
return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
}
case IITDescriptor::TruncArgument: {
Type *Ty = Tys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
return VectorType::getTruncatedElementVectorType(VTy);
IntegerType *ITy = cast<IntegerType>(Ty);
assert(ITy->getBitWidth() % 2 == 0);
return IntegerType::get(Context, ITy->getBitWidth() / 2);
}
case IITDescriptor::HalfVecArgument:
return VectorType::getHalfElementsVectorType(cast<VectorType>(
Tys[D.getArgumentNumber()]));
case IITDescriptor::SameVecWidthArgument: {
Type *EltTy = DecodeFixedType(Infos, Tys, Context);
Type *Ty = Tys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
return VectorType::get(EltTy, VTy->getNumElements());
}
llvm_unreachable("unhandled");
}
case IITDescriptor::PtrToArgument: {
Type *Ty = Tys[D.getArgumentNumber()];
return PointerType::getUnqual(Ty);
}
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());
}
}
llvm_unreachable("unhandled");
}
FunctionType *Intrinsic::getType(LLVMContext &Context,
ID id, ArrayRef<Type*> Tys) {
SmallVector<IITDescriptor, 8> Table;
getIntrinsicInfoTableEntries(id, Table);
ArrayRef<IITDescriptor> TableRef = Table;
Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
SmallVector<Type*, 8> ArgTys;
while (!TableRef.empty())
ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {
ArgTys.pop_back();
return FunctionType::get(ResultTy, ArgTys, true);
}
return FunctionType::get(ResultTy, ArgTys, false);
}
bool Intrinsic::isOverloaded(ID id) {
#define GET_INTRINSIC_OVERLOAD_TABLE
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_OVERLOAD_TABLE
}
bool Intrinsic::isLeaf(ID id) {
switch (id) {
default:
return true;
case Intrinsic::experimental_gc_statepoint:
case Intrinsic::experimental_patchpoint_void:
case Intrinsic::experimental_patchpoint_i64:
return false;
}
}
#define GET_INTRINSIC_ATTRIBUTES
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_ATTRIBUTES
Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
return
cast<Function>(M->getOrInsertFunction(getName(id, Tys),
getType(M->getContext(), id, Tys)));
}
#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
#include "llvm/IR/Intrinsics.gen"
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
#include "llvm/IR/Intrinsics.gen"
#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
bool Function::hasAddressTaken(const User* *PutOffender) const {
for (const Use &U : uses()) {
const User *FU = U.getUser();
if (isa<BlockAddress>(FU))
continue;
if (!isa<CallInst>(FU) && !isa<InvokeInst>(FU))
return PutOffender ? (*PutOffender = FU, true) : true;
ImmutableCallSite CS(cast<Instruction>(FU));
if (!CS.isCallee(&U))
return PutOffender ? (*PutOffender = FU, true) : true;
}
return false;
}
bool Function::isDefTriviallyDead() const {
if (!hasLinkOnceLinkage() && !hasLocalLinkage() &&
!hasAvailableExternallyLinkage())
return false;
for (const User *U : users())
if (!isa<BlockAddress>(U))
return false;
return true;
}
bool Function::callsFunctionThatReturnsTwice() const {
for (const_inst_iterator
I = inst_begin(this), E = inst_end(this); I != E; ++I) {
ImmutableCallSite CS(&*I);
if (CS && CS.hasFnAttr(Attribute::ReturnsTwice))
return true;
}
return false;
}
static Constant *
getFunctionData(const Function *F,
const LLVMContextImpl::FunctionDataMapTy &Map) {
const auto &Entry = Map.find(F);
assert(Entry != Map.end());
return cast<Constant>(Entry->second->getReturnValue());
}
static unsigned setFunctionData(Function *F,
LLVMContextImpl::FunctionDataMapTy &Map,
Constant *Data, unsigned SCData, unsigned Bit) {
ReturnInst *&Holder = Map[F];
if (Data) {
if (Holder)
Holder->setOperand(0, Data);
else
Holder = ReturnInst::Create(F->getContext(), Data);
return SCData | (1 << Bit);
} else {
delete Holder;
Map.erase(F);
return SCData & ~(1 << Bit);
}
}
Constant *Function::getPrefixData() const {
assert(hasPrefixData());
return getFunctionData(this, getContext().pImpl->PrefixDataMap);
}
void Function::setPrefixData(Constant *PrefixData) {
if (!PrefixData && !hasPrefixData())
return;
unsigned SCData = getSubclassDataFromValue();
SCData = setFunctionData(this, getContext().pImpl->PrefixDataMap, PrefixData,
SCData, 1);
setValueSubclassData(SCData);
}
Constant *Function::getPrologueData() const {
assert(hasPrologueData());
return getFunctionData(this, getContext().pImpl->PrologueDataMap);
}
void Function::setPrologueData(Constant *PrologueData) {
if (!PrologueData && !hasPrologueData())
return;
unsigned SCData = getSubclassDataFromValue();
SCData = setFunctionData(this, getContext().pImpl->PrologueDataMap,
PrologueData, SCData, 2);
setValueSubclassData(SCData);
}
void Function::setEntryCount(uint64_t Count) {
MDBuilder MDB(getContext());
setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(Count));
}
Optional<uint64_t> Function::getEntryCount() const {
MDNode *MD = getMetadata(LLVMContext::MD_prof);
if (MD && 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));
return CI->getValue().getZExtValue();
}
return None;
}
void Function::setPersonalityFn(Constant *C) {
if (!C) {
if (hasPersonalityFn()) {
Op<0>().set(nullptr);
setFunctionNumOperands(0);
}
} else {
if (!hasPersonalityFn())
setFunctionNumOperands(1);
Op<0>().set(C);
}
}