X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FIR%2FFunction.cpp;h=9e622bdc99b496a952e8a6950ad6d3dc510dd26c;hp=6d418a4c366a08a3e8e681a0775146c8ae15e909;hb=10646db916c8a623670e3c1829797e850f4de15d;hpb=4bbfbdf7d7a3c4dbdd2d7bb190ef8a0a8246c218 diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 6d418a4c366..9e622bdc99b 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -23,8 +23,8 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" -#include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/RWMutex.h" #include "llvm/Support/StringPool.h" @@ -44,7 +44,7 @@ void Argument::anchor() { } Argument::Argument(Type *Ty, const Twine &Name, Function *Par) : Value(Ty, Value::ArgumentVal) { - Parent = 0; + Parent = nullptr; // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -76,6 +76,20 @@ unsigned Argument::getArgNo() const { 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)) + return true; + else if (getDereferenceableBytes() > 0 && + getType()->getPointerAddressSpace() == 0) + return true; + return false; +} + /// hasByValAttr - Return true if this argument has the byval attribute on it /// in its containing function. bool Argument::hasByValAttr() const { @@ -105,6 +119,12 @@ unsigned Argument::getParamAlignment() const { } +uint64_t Argument::getDereferenceableBytes() const { + assert(getType()->isPointerTy() && + "Only pointers have dereferenceable bytes"); + return getParent()->getDereferenceableBytes(getArgNo()+1); +} + /// hasNestAttr - Return true if this argument has the nest attribute on /// it in its containing function. bool Argument::hasNestAttr() const { @@ -146,6 +166,20 @@ bool Argument::hasReturnedAttr() const { hasAttribute(getArgNo()+1, Attribute::Returned); } +/// hasZExtAttr - Return true if this argument has the zext attribute on it in +/// its containing function. +bool Argument::hasZExtAttr() const { + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::ZExt); +} + +/// hasSExtAttr Return true if this argument has the sext attribute on it in its +/// containing function. +bool Argument::hasSExtAttr() const { + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::SExt); +} + /// Return true if this argument has the readonly or readnone attribute on it /// in its containing function. bool Argument::onlyReadsMemory() const { @@ -209,8 +243,8 @@ void Function::eraseFromParent() { Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name, Module *ParentModule) - : GlobalValue(PointerType::getUnqual(Ty), - Value::FunctionVal, 0, 0, Linkage, name) { + : GlobalObject(PointerType::getUnqual(Ty), + Value::FunctionVal, nullptr, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && "invalid return type"); SymTab = new ValueSymbolTable(); @@ -293,7 +327,7 @@ void Function::dropAllReferences() { BasicBlocks.begin()->eraseFromParent(); // Prefix data is stored in a side table. - setPrefixData(0); + setPrefixData(nullptr); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -348,10 +382,10 @@ void Function::clearGC() { GCNames->erase(this); if (GCNames->empty()) { delete GCNames; - GCNames = 0; + GCNames = nullptr; if (GCNamePool->empty()) { delete GCNamePool; - GCNamePool = 0; + GCNamePool = nullptr; } } } @@ -361,7 +395,7 @@ void Function::clearGC() { /// create a Function) from the Function Src to this one. void Function::copyAttributesFrom(const GlobalValue *Src) { assert(isa(Src) && "Expected a Function!"); - GlobalValue::copyAttributesFrom(Src); + GlobalObject::copyAttributesFrom(Src); const Function *SrcF = cast(Src); setCallingConv(SrcF->getCallingConv()); setAttributes(SrcF->getAttributes()); @@ -372,7 +406,7 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { if (SrcF->hasPrefixData()) setPrefixData(SrcF->getPrefixData()); else - setPrefixData(0); + setPrefixData(nullptr); } /// getIntrinsicID - This method returns the ID number of the specified @@ -459,18 +493,20 @@ enum IIT_Info { IIT_ARG = 15, // Values from 16+ are only encodable with the inefficient encoding. - IIT_MMX = 16, - IIT_METADATA = 17, - IIT_EMPTYSTRUCT = 18, - IIT_STRUCT2 = 19, - IIT_STRUCT3 = 20, - IIT_STRUCT4 = 21, - IIT_STRUCT5 = 22, - IIT_EXTEND_VEC_ARG = 23, - IIT_TRUNC_VEC_ARG = 24, - IIT_ANYPTR = 25, - IIT_V1 = 26, - IIT_VARARG = 27 + IIT_V64 = 16, + IIT_MMX = 17, + IIT_METADATA = 18, + IIT_EMPTYSTRUCT = 19, + IIT_STRUCT2 = 20, + IIT_STRUCT3 = 21, + IIT_STRUCT4 = 22, + IIT_STRUCT5 = 23, + IIT_EXTEND_ARG = 24, + IIT_TRUNC_ARG = 25, + IIT_ANYPTR = 26, + IIT_V1 = 27, + IIT_VARARG = 28, + IIT_HALF_VEC_ARG = 29 }; @@ -541,6 +577,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, 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); @@ -556,15 +596,21 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo)); return; } - case IIT_EXTEND_VEC_ARG: { + 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::ExtendVecArgument, + OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo)); return; } - case IIT_TRUNC_VEC_ARG: { + case IIT_HALF_VEC_ARG: { unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); - OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncVecArgument, + OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument, ArgInfo)); return; } @@ -651,17 +697,29 @@ static Type *DecodeFixedType(ArrayRef &Infos, 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, ArrayRef(Elts,D.Struct_NumElements)); + return StructType::get(Context, makeArrayRef(Elts,D.Struct_NumElements)); } case IITDescriptor::Argument: return Tys[D.getArgumentNumber()]; - case IITDescriptor::ExtendVecArgument: - return VectorType::getExtendedElementVectorType(cast( - Tys[D.getArgumentNumber()])); + case IITDescriptor::ExtendArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(Ty)) + return VectorType::getExtendedElementVectorType(VTy); - case IITDescriptor::TruncVecArgument: - return VectorType::getTruncatedElementVectorType(cast( + return IntegerType::get(Context, 2 * cast(Ty)->getBitWidth()); + } + case IITDescriptor::TruncArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(Ty)) + return VectorType::getTruncatedElementVectorType(VTy); + + IntegerType *ITy = cast(Ty); + assert(ITy->getBitWidth() % 2 == 0); + return IntegerType::get(Context, ITy->getBitWidth() / 2); + } + case IITDescriptor::HalfVecArgument: + return VectorType::getHalfElementsVectorType(cast( Tys[D.getArgumentNumber()])); } llvm_unreachable("unhandled"); @@ -681,6 +739,12 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, while (!TableRef.empty()) ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context)); + // DecodeFixedType returns Void for IITDescriptor::Void and IITDescriptor::VarArg + // If we see void type as the type of the last argument, it is vararg intrinsic + if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) { + ArgTys.pop_back(); + return FunctionType::get(ResultTy, ArgTys, true); + } return FunctionType::get(ResultTy, ArgTys, false); } @@ -708,18 +772,23 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef Tys) { #include "llvm/IR/Intrinsics.gen" #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" +#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) { - const User *U = *I; - if (isa(U)) + for (const Use &U : uses()) { + const User *FU = U.getUser(); + if (isa(FU)) continue; - if (!isa(U) && !isa(U)) - return PutOffender ? (*PutOffender = U, true) : true; - ImmutableCallSite CS(cast(U)); - if (!CS.isCallee(I)) - return PutOffender ? (*PutOffender = U, true) : true; + if (!isa(FU) && !isa(FU)) + return PutOffender ? (*PutOffender = FU, true) : true; + ImmutableCallSite CS(cast(FU)); + if (!CS.isCallee(&U)) + return PutOffender ? (*PutOffender = FU, true) : true; } return false; } @@ -731,8 +800,8 @@ bool Function::isDefTriviallyDead() const { return false; // Check if the function is used by anything other than a blockaddress. - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) - if (!isa(*I)) + for (const User *U : users()) + if (!isa(U)) return false; return true;