X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FFunction.cpp;h=bda2eff4c99c3b48140e1ac7938f8e6fa225f742;hb=3f142c36ad04c1aabac90df6a866bd2b0767f24f;hp=0cf808c507c51cd9573977c61ab264c48a2120dd;hpb=08e78b18b8ef2c939ee95469662c98e23846d860;p=oota-llvm.git diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 0cf808c507c..bda2eff4c99 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -14,18 +14,16 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/IntrinsicInst.h" -#include "llvm/ParameterAttributes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/StringPool.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 = new BasicBlock(); + BasicBlock *Ret = BasicBlock::Create(); // This should not be garbage monitored. LeakDetector::removeGarbageObject(Ret); return Ret; @@ -93,25 +91,41 @@ unsigned Argument::getArgNo() const { /// in its containing function. bool Argument::hasByValAttr() const { if (!isa(getType())) return false; - return getParent()->paramHasAttr(getArgNo()+1, ParamAttr::ByVal); + return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal); } /// 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); + 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; + 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 (this != getParent()->arg_begin()) return false; // StructRet param must be first param - return getParent()->paramHasAttr(1, ParamAttr::StructRet); + if (this != getParent()->arg_begin()) + return false; // StructRet param must be first param + return getParent()->paramHasAttr(1, Attribute::StructRet); } +/// addAttr - Add a Attribute to an argument +void Argument::addAttr(Attributes attr) { + getParent()->addAttribute(getArgNo() + 1, attr); +} +/// removeAttr - Remove a Attribute from an argument +void Argument::removeAttr(Attributes attr) { + getParent()->removeAttribute(getArgNo() + 1, attr); +} //===----------------------------------------------------------------------===// @@ -138,41 +152,6 @@ void Function::eraseFromParent() { getParent()->getFunctionList().erase(this); } -/// @brief Determine whether the function has the given attribute. -bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - return ParamAttrs && ParamAttrs->paramHasAttr(i, attr); -} - -/// @brief Extract the alignment for a call or parameter (0=unknown). -uint16_t Function::getParamAlignment(uint16_t i) const { - return ParamAttrs ? ParamAttrs->getParamAlignment(i) : 0; -} - -/// @brief Determine if the function cannot return. -bool Function::doesNotReturn() const { - return paramHasAttr(0, ParamAttr::NoReturn); -} - -/// @brief Determine if the function cannot unwind. -bool Function::doesNotThrow() const { - return paramHasAttr(0, ParamAttr::NoUnwind); -} - -/// @brief Determine if the function does not access memory. -bool Function::doesNotAccessMemory() const { - return paramHasAttr(0, ParamAttr::ReadNone); -} - -/// @brief Determine if the function does not access or only reads memory. -bool Function::onlyReadsMemory() const { - return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); -} - -/// @brief Determine if the function returns a structure. -bool Function::isStructReturn() const { - return paramHasAttr(1, ParamAttr::StructRet); -} - //===----------------------------------------------------------------------===// // Function Implementation //===----------------------------------------------------------------------===// @@ -180,14 +159,11 @@ bool Function::isStructReturn() const { Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) : GlobalValue(PointerType::getUnqual(Ty), - Value::FunctionVal, 0, 0, Linkage, name), - ParamAttrs(0) { + Value::FunctionVal, 0, 0, Linkage, name) { + assert(FunctionType::isValidReturnType(getReturnType()) && + !isa(getReturnType()) && "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. @@ -197,6 +173,11 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, if (ParentModule) ParentModule->getFunctionList().push_back(this); + + // Ensure intrinsics have the right parameter attributes. + if (unsigned IID = getIntrinsicID(true)) + setAttributes(Intrinsic::getAttributes(Intrinsic::ID(IID))); + } Function::~Function() { @@ -206,12 +187,8 @@ Function::~Function() { ArgumentList.clear(); delete SymTab; - // Drop our reference to the parameter attributes, if any. - if (ParamAttrs) - ParamAttrs->dropRef(); - - // Remove the function from the on-the-side collector table. - clearCollector(); + // Remove the function from the on-the-side GC table. + clearGC(); } void Function::BuildLazyArguments() const { @@ -242,24 +219,6 @@ void Function::setParent(Module *parent) { LeakDetector::removeGarbageObject(this); } -void Function::setParamAttrs(const ParamAttrsList *attrs) { - // Avoid deleting the ParamAttrsList if they are setting the - // attributes to the same list. - if (ParamAttrs == attrs) - return; - - // Drop reference on the old ParamAttrsList - if (ParamAttrs) - ParamAttrs->dropRef(); - - // Add reference to the new ParamAttrsList - if (attrs) - attrs->addRef(); - - // Set the new ParamAttrsList. - ParamAttrs = attrs; -} - // dropAllReferences() - This function causes all the subinstructions to "let // go" of all references that they are maintaining. This allows one to // 'delete' a whole class at a time, even though there may be circular @@ -274,44 +233,70 @@ void Function::dropAllReferences() { BasicBlocks.clear(); // Delete all basic blocks... } -// Maintain the collector name for each function in an on-the-side table. This -// saves allocating an additional word in Function for programs which do not use -// GC (i.e., most programs) at the cost of increased overhead for clients which -// do use GC. -static DenseMap *CollectorNames; -static StringPool *CollectorNamePool; +void Function::addAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); + PAL = PAL.addAttr(i, attr); + setAttributes(PAL); +} -bool Function::hasCollector() const { - return CollectorNames && CollectorNames->count(this); +void Function::removeAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); + PAL = PAL.removeAttr(i, attr); + setAttributes(PAL); } -const char *Function::getCollector() const { - assert(hasCollector() && "Function has no collector"); - return *(*CollectorNames)[this]; +// Maintain the GC name for each function in an on-the-side table. This saves +// allocating an additional word in Function for programs which do not use GC +// (i.e., most programs) at the cost of increased overhead for clients which do +// use GC. +static DenseMap *GCNames; +static StringPool *GCNamePool; + +bool Function::hasGC() const { + return GCNames && GCNames->count(this); } -void Function::setCollector(const char *Str) { - if (!CollectorNamePool) - CollectorNamePool = new StringPool(); - if (!CollectorNames) - CollectorNames = new DenseMap(); - (*CollectorNames)[this] = CollectorNamePool->intern(Str); +const char *Function::getGC() const { + assert(hasGC() && "Function has no collector"); + return *(*GCNames)[this]; } -void Function::clearCollector() { - if (CollectorNames) { - CollectorNames->erase(this); - if (CollectorNames->empty()) { - delete CollectorNames; - CollectorNames = 0; - if (CollectorNamePool->empty()) { - delete CollectorNamePool; - CollectorNamePool = 0; +void Function::setGC(const char *Str) { + if (!GCNamePool) + GCNamePool = new StringPool(); + if (!GCNames) + GCNames = new DenseMap(); + (*GCNames)[this] = GCNamePool->intern(Str); +} + +void Function::clearGC() { + if (GCNames) { + GCNames->erase(this); + if (GCNames->empty()) { + delete GCNames; + GCNames = 0; + if (GCNamePool->empty()) { + delete GCNamePool; + GCNamePool = 0; } } } } +/// copyAttributesFrom - copy all additional attributes (those not needed to +/// 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); + const Function *SrcF = cast(Src); + setCallingConv(SrcF->getCallingConv()); + setAttributes(SrcF->getAttributes()); + if (SrcF->hasGC()) + setGC(SrcF->getGC()); + else + clearGC(); +} + /// getIntrinsicID - This method returns the ID number of the specified /// function, or Intrinsic::not_intrinsic if the function is not an /// intrinsic, or if the pointer is null. This value is always defined to be @@ -350,9 +335,14 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { if (numTys == 0) return Table[id]; std::string Result(Table[id]); - for (unsigned i = 0; i < numTys; ++i) - if (Tys[i]) - Result += "." + MVT::getValueTypeString(MVT::getValueType(Tys[i])); + 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(); + } + else if (Tys[i]) + Result += "." + MVT::getMVT(Tys[i]).getMVTString(); + } return Result; } @@ -369,54 +359,18 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys, return FunctionType::get(ResultTy, ArgTys, IsVarArg); } -const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { - ParamAttrsVector Attrs; - ParameterAttributes Attr = ParamAttr::None; - +/// 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; - - Attrs.push_back(ParamAttrsWithIndex::get(0, Attr)); - return ParamAttrsList::get(Attrs); -} - 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. - Function *F = + return cast(M->getOrInsertFunction(getName(id, Tys, numTys), getType(id, Tys, numTys))); - F->setParamAttrs(getParamAttrs(id)); - return F; -} - -Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { - if (ConstantExpr *CE = dyn_cast(Ptr)) { - if (CE->getOpcode() == Instruction::BitCast) { - if (isa(CE->getOperand(0)->getType())) - return StripPointerCasts(CE->getOperand(0)); - } else if (CE->getOpcode() == Instruction::GetElementPtr) { - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) - if (!CE->getOperand(i)->isNullValue()) - return Ptr; - return StripPointerCasts(CE->getOperand(0)); - } - return Ptr; - } - - if (BitCastInst *CI = dyn_cast(Ptr)) { - if (isa(CI->getOperand(0)->getType())) - return StripPointerCasts(CI->getOperand(0)); - } else if (GetElementPtrInst *GEP = dyn_cast(Ptr)) { - if (GEP->hasAllZeroIndices()) - return StripPointerCasts(GEP->getOperand(0)); - } - return Ptr; } // vim: sw=2 ai