X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FFunction.cpp;h=00d1d7873247736ca734b950449f53b38ebf9f10;hb=6c3541d5597033bdb2f26f5ade811b482c32a39a;hp=6cf2c8186f9be09ecdf602ea85edad745d00a0c7;hpb=1e0dc8e12396ee8021c91c6115585f5877f35efb;p=oota-llvm.git diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 6cf2c8186f9..00d1d787324 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -16,11 +16,12 @@ #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/System/RWMutex.h" -#include "llvm/System/Threading.h" +#include "llvm/Support/RWMutex.h" +#include "llvm/Support/Threading.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" @@ -29,8 +30,8 @@ using namespace llvm; // 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 @@ -73,28 +74,35 @@ 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; + 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; + 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 (!isa(getType())) return false; + 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, Attribute::StructRet); @@ -148,12 +156,12 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, : GlobalValue(PointerType::getUnqual(Ty), Value::FunctionVal, 0, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && - !isa(getReturnType()) && "invalid return type"); + !getReturnType()->isOpaqueTy() && "invalid return type"); SymTab = new ValueSymbolTable(); // 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); @@ -182,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::getVoidTy(FT->getContext()) && + 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 { @@ -218,19 +227,10 @@ void Function::dropAllReferences() { for (iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); - // Delete all basic blocks. - while (!BasicBlocks.empty()) { - // If there is still a reference to the block, it must be a 'blockaddress' - // constant pointing to it. Just replace the BlockAddress with undef. - BasicBlock *BB = BasicBlocks.begin(); - if (!BB->use_empty()) { - BlockAddress *BA = cast(BB->use_back()); - BA->replaceAllUsesWith(UndefValue::get(BA->getType())); - BA->destroyConstant(); - } - - BB->eraseFromParent(); - } + // 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::addAttribute(unsigned i, Attributes attr) { @@ -392,13 +392,16 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, #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 { - for (Value::use_const_iterator I = use_begin(), E = use_end(); I != E; ++I) { - if (I.getOperandNo() != 0 || - (!isa(*I) && !isa(*I))) - return true; +/// 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; }