X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FFunction.cpp;h=f1fe6604333462a01f5b483a1243404f5212a82f;hb=0c5071f56198367ea2b29f8e34ddb9ecd1773985;hp=970bbaeed8b524c46e852840f7cb137eec26f7af;hpb=4b70bfc905f3ac68a8429f9fe0016e30433b3b0c;p=oota-llvm.git diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 970bbaeed8b..f1fe6604333 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -18,13 +18,13 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/DerivedTypes.h" +#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/CallSite.h" -#include "llvm/Support/InstIterator.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 { @@ -92,12 +106,25 @@ bool Argument::hasInAllocaAttr() const { 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); +} + /// hasNestAttr - Return true if this argument has the nest attribute on /// it in its containing function. bool Argument::hasNestAttr() const { @@ -139,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 { @@ -202,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(); @@ -286,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) { @@ -341,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; } } } @@ -354,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()); @@ -365,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,11 +500,12 @@ enum IIT_Info { IIT_STRUCT3 = 20, IIT_STRUCT4 = 21, IIT_STRUCT5 = 22, - IIT_EXTEND_VEC_ARG = 23, - IIT_TRUNC_VEC_ARG = 24, + IIT_EXTEND_ARG = 23, + IIT_TRUNC_ARG = 24, IIT_ANYPTR = 25, IIT_V1 = 26, - IIT_VARARG = 27 + IIT_VARARG = 27, + IIT_HALF_VEC_ARG = 28 }; @@ -549,15 +591,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; } @@ -649,12 +697,24 @@ static Type *DecodeFixedType(ArrayRef &Infos, 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"); @@ -701,18 +761,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; } @@ -724,8 +789,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; @@ -736,10 +801,8 @@ bool Function::isDefTriviallyDead() const { bool Function::callsFunctionThatReturnsTwice() const { for (const_inst_iterator I = inst_begin(this), E = inst_end(this); I != E; ++I) { - const CallInst* callInst = dyn_cast(&*I); - if (!callInst) - continue; - if (callInst->canReturnTwice()) + ImmutableCallSite CS(&*I); + if (CS && CS.hasFnAttr(Attribute::ReturnsTwice)) return true; }