X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FFunction.cpp;h=00d1d7873247736ca734b950449f53b38ebf9f10;hb=6c3541d5597033bdb2f26f5ade811b482c32a39a;hp=2602443ab9f122cae51b82713a77fd3cd8aea6ff;hpb=e3d76d37e972d6f7b1335a3944ce31ae8f4cd3c9;p=oota-llvm.git diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 2602443ab9f..00d1d787324 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -14,47 +14,30 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StringPool.h" +#include "llvm/Support/RWMutex.h" +#include "llvm/Support/Threading.h" #include "SymbolTableListTraitsImpl.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; -BasicBlock *ilist_traits::createSentinel() { - BasicBlock *Ret = BasicBlock::Create(); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} - -iplist &ilist_traits::getList(Function *F) { - return F->getBasicBlockList(); -} - -Argument *ilist_traits::createSentinel() { - Argument *Ret = new Argument(Type::Int32Ty); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} - -iplist &ilist_traits::getList(Function *F) { - return F->getArgumentList(); -} // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits; -template class SymbolTableListTraits; +template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; //===----------------------------------------------------------------------===// // Argument Implementation //===----------------------------------------------------------------------===// -Argument::Argument(const Type *Ty, const std::string &Name, Function *Par) +Argument::Argument(const Type *Ty, const Twine &Name, Function *Par) : Value(Ty, Value::ArgumentVal) { Parent = 0; @@ -91,34 +74,48 @@ unsigned Argument::getArgNo() const { /// hasByValAttr - Return true if this argument has the byval attribute on it /// in its containing function. bool Argument::hasByValAttr() const { - if (!isa(getType())) return false; - return getParent()->paramHasAttr(getArgNo()+1, ParamAttr::ByVal); + if (!getType()->isPointerTy()) return false; + return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal); +} + +/// 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 getParent()->paramHasAttr(getArgNo()+1, Attribute::Nest); } /// hasNoAliasAttr - Return true if this argument has the noalias attribute on /// it in its containing function. bool Argument::hasNoAliasAttr() const { - if (!isa(getType())) return false; - return getParent()->paramHasAttr(getArgNo()+1, ParamAttr::NoAlias); + if (!getType()->isPointerTy()) return false; + return getParent()->paramHasAttr(getArgNo()+1, 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 getParent()->paramHasAttr(getArgNo()+1, Attribute::NoCapture); } /// hasSRetAttr - Return true if this argument has the sret attribute on /// it in its containing function. bool Argument::hasStructRetAttr() const { - if (!isa(getType())) return false; + if (!getType()->isPointerTy()) return false; if (this != getParent()->arg_begin()) return false; // StructRet param must be first param - return getParent()->paramHasAttr(1, ParamAttr::StructRet); + return getParent()->paramHasAttr(1, Attribute::StructRet); } -/// addAttr - Add a ParamAttr to an argument +/// addAttr - Add a Attribute to an argument void Argument::addAttr(Attributes attr) { - getParent()->addParamAttr(getArgNo() + 1, attr); + getParent()->addAttribute(getArgNo() + 1, attr); } -/// removeAttr - Remove a ParamAttr from an argument +/// removeAttr - Remove a Attribute from an argument void Argument::removeAttr(Attributes attr) { - getParent()->removeParamAttr(getArgNo() + 1, attr); + getParent()->removeAttribute(getArgNo() + 1, attr); } @@ -126,6 +123,10 @@ void Argument::removeAttr(Attributes attr) { // Helper Methods in Function //===----------------------------------------------------------------------===// +LLVMContext &Function::getContext() const { + return getType()->getContext(); +} + const FunctionType *Function::getFunctionType() const { return cast(getType()->getElementType()); } @@ -151,18 +152,16 @@ void Function::eraseFromParent() { //===----------------------------------------------------------------------===// Function::Function(const FunctionType *Ty, LinkageTypes Linkage, - const std::string &name, Module *ParentModule) + const Twine &name, Module *ParentModule) : GlobalValue(PointerType::getUnqual(Ty), Value::FunctionVal, 0, 0, Linkage, name) { + assert(FunctionType::isValidReturnType(getReturnType()) && + !getReturnType()->isOpaqueTy() && "invalid return type"); SymTab = new ValueSymbolTable(); - assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy - || isa(getReturnType())) - && "LLVM functions cannot return aggregate values!"); - // If the function has arguments, mark them as lazily built. if (Ty->getNumParams()) - SubclassData = 1; // Set the "has lazy arguments" bit. + setValueSubclassData(1); // Set the "has lazy arguments" bit. // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -171,8 +170,8 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, ParentModule->getFunctionList().push_back(this); // Ensure intrinsics have the right parameter attributes. - if (unsigned IID = getIntrinsicID(true)) - setParamAttrs(Intrinsic::getParamAttrs(Intrinsic::ID(IID))); + if (unsigned IID = getIntrinsicID()) + setAttributes(Intrinsic::getAttributes(Intrinsic::ID(IID))); } @@ -191,13 +190,14 @@ void Function::BuildLazyArguments() const { // Create the arguments vector, all arguments start out unnamed. const FunctionType *FT = getFunctionType(); for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - assert(FT->getParamType(i) != Type::VoidTy && + assert(!FT->getParamType(i)->isVoidTy() && "Cannot have void typed arguments!"); ArgumentList.push_back(new Argument(FT->getParamType(i))); } // Clear the lazy arguments bit. - const_cast(this)->SubclassData &= ~1; + unsigned SDC = getSubclassDataFromValue(); + const_cast(this)->setValueSubclassData(SDC &= ~1); } size_t Function::arg_size() const { @@ -226,19 +226,23 @@ void Function::setParent(Module *parent) { void Function::dropAllReferences() { for (iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); - BasicBlocks.clear(); // Delete all basic blocks... + + // Delete all basic blocks. They are now unused, except possibly by + // blockaddresses, but BasicBlock's destructor takes care of those. + while (!BasicBlocks.empty()) + BasicBlocks.begin()->eraseFromParent(); } -void Function::addParamAttr(unsigned i, Attributes attr) { - PAListPtr PAL = getParamAttrs(); +void Function::addAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.addAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } -void Function::removeParamAttr(unsigned i, Attributes attr) { - PAListPtr PAL = getParamAttrs(); +void Function::removeAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.removeAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } // Maintain the GC name for each function in an on-the-side table. This saves @@ -247,17 +251,21 @@ void Function::removeParamAttr(unsigned i, Attributes attr) { // use GC. static DenseMap *GCNames; static StringPool *GCNamePool; +static ManagedStatic > GCLock; bool Function::hasGC() const { + sys::SmartScopedReader Reader(*GCLock); return GCNames && GCNames->count(this); } const char *Function::getGC() const { assert(hasGC() && "Function has no collector"); + sys::SmartScopedReader Reader(*GCLock); return *(*GCNames)[this]; } void Function::setGC(const char *Str) { + sys::SmartScopedWriter Writer(*GCLock); if (!GCNamePool) GCNamePool = new StringPool(); if (!GCNames) @@ -266,6 +274,7 @@ void Function::setGC(const char *Str) { } void Function::clearGC() { + sys::SmartScopedWriter Writer(*GCLock); if (GCNames) { GCNames->erase(this); if (GCNames->empty()) { @@ -286,7 +295,7 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { GlobalValue::copyAttributesFrom(Src); const Function *SrcF = cast(Src); setCallingConv(SrcF->getCallingConv()); - setParamAttrs(SrcF->getParamAttrs()); + setAttributes(SrcF->getAttributes()); if (SrcF->hasGC()) setGC(SrcF->getGC()); else @@ -300,7 +309,7 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { /// particular intrinsic functions which correspond to this value are defined in /// llvm/Intrinsics.h. /// -unsigned Function::getIntrinsicID(bool noAssert) const { +unsigned Function::getIntrinsicID() const { const ValueName *ValName = this->getValueName(); if (!ValName) return 0; @@ -311,12 +320,9 @@ unsigned Function::getIntrinsicID(bool noAssert) const { || Name[2] != 'v' || Name[3] != 'm') return 0; // All intrinsics start with 'llvm.' - assert((Len != 5 || noAssert) && "'llvm.' is an invalid intrinsic name!"); - #define GET_FUNCTION_RECOGNIZER #include "llvm/Intrinsics.gen" #undef GET_FUNCTION_RECOGNIZER - assert(noAssert && "Invalid LLVM intrinsic name"); return 0; } @@ -334,15 +340,16 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { for (unsigned i = 0; i < numTys; ++i) { if (const PointerType* PTyp = dyn_cast(Tys[i])) { Result += ".p" + llvm::utostr(PTyp->getAddressSpace()) + - MVT::getMVT(PTyp->getElementType()).getMVTString(); + EVT::getEVT(PTyp->getElementType()).getEVTString(); } else if (Tys[i]) - Result += "." + MVT::getMVT(Tys[i]).getMVTString(); + Result += "." + EVT::getEVT(Tys[i]).getEVTString(); } return Result; } -const FunctionType *Intrinsic::getType(ID id, const Type **Tys, +const FunctionType *Intrinsic::getType(LLVMContext &Context, + ID id, const Type **Tys, unsigned numTys) { const Type *ResultTy = NULL; std::vector ArgTys; @@ -355,27 +362,48 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys, return FunctionType::get(ResultTy, ArgTys, IsVarArg); } -PAListPtr Intrinsic::getParamAttrs(ID id) { - Attributes Attr = ParamAttr::None; +bool Intrinsic::isOverloaded(ID id) { + const bool OTable[] = { + false, +#define GET_INTRINSIC_OVERLOAD_TABLE +#include "llvm/Intrinsics.gen" +#undef GET_INTRINSIC_OVERLOAD_TABLE + }; + return OTable[id]; +} +/// This defines the "Intrinsic::getAttributes(ID id)" method. #define GET_INTRINSIC_ATTRIBUTES #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_ATTRIBUTES - // Intrinsics cannot throw exceptions. - Attr |= ParamAttr::NoUnwind; - - FnAttributeWithIndex PAWI = FnAttributeWithIndex::get(0, Attr); - return PAListPtr::get(&PAWI, 1); -} - Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, unsigned numTys) { // There can never be multiple globals with the same name of different types, // because intrinsics must be a specific type. return cast(M->getOrInsertFunction(getName(id, Tys, numTys), - getType(id, Tys, numTys))); + getType(M->getContext(), + id, Tys, numTys))); +} + +// This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method. +#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN +#include "llvm/Intrinsics.gen" +#undef GET_LLVM_INTRINSIC_FOR_GCC_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) && !isa(U)) + return PutOffender ? (*PutOffender = U, true) : true; + ImmutableCallSite CS(cast(U)); + if (!CS.isCallee(I)) + return PutOffender ? (*PutOffender = U, true) : true; + } + return false; } // vim: sw=2 ai