X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FFunction.cpp;h=dd781964a9174ad28bb215a4a1132fab8cf9352f;hb=bb862c042fd773354645382ad0511b165b33116e;hp=72237eb440464e2060da99bea32bf101bd50a273;hpb=95af592a631f403e1458ec1155f89fc31011572c;p=oota-llvm.git diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 72237eb4404..dd781964a91 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -13,8 +13,10 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" #include "llvm/IntrinsicInst.h" #include "llvm/Support/LeakDetector.h" +#include "llvm/Support/ManagedStatic.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -43,15 +45,15 @@ iplist &ilist_traits::getList(Function *F) { // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits; -template class SymbolTableListTraits; +template class SymbolTableListTraits; +template class SymbolTableListTraits; //===----------------------------------------------------------------------===// // Argument Implementation //===----------------------------------------------------------------------===// Argument::Argument(const Type *Ty, const std::string &Name, Function *Par) - : Value(Ty, Value::ArgumentVal, Name) { + : Value(Ty, Value::ArgumentVal) { Parent = 0; // Make sure that we get added to a function @@ -59,6 +61,7 @@ Argument::Argument(const Type *Ty, const std::string &Name, Function *Par) if (Par) Par->getArgumentList().push_back(this); + setName(Name); } void Argument::setParent(Function *parent) { @@ -69,6 +72,71 @@ void Argument::setParent(Function *parent) { LeakDetector::removeGarbageObject(this); } +//===----------------------------------------------------------------------===// +// ParamAttrsList Implementation +//===----------------------------------------------------------------------===// + +uint16_t +ParamAttrsList::getParamAttrs(uint16_t Index) const { + unsigned limit = attrs.size(); + for (unsigned i = 0; i < limit; ++i) + if (attrs[i].index == Index) + return attrs[i].attrs; + return ParamAttr::None; +} + + +std::string +ParamAttrsList::getParamAttrsText(uint16_t Attrs) { + std::string Result; + if (Attrs & ParamAttr::ZExt) + Result += "zeroext "; + if (Attrs & ParamAttr::SExt) + Result += "signext "; + if (Attrs & ParamAttr::NoReturn) + Result += "noreturn "; + if (Attrs & ParamAttr::NoUnwind) + Result += "nounwind "; + if (Attrs & ParamAttr::InReg) + Result += "inreg "; + if (Attrs & ParamAttr::NoAlias) + Result += "noalias "; + if (Attrs & ParamAttr::StructRet) + Result += "sret "; + if (Attrs & ParamAttr::ByVal) + Result += "byval "; + return Result; +} + +void +ParamAttrsList::Profile(FoldingSetNodeID &ID) const { + for (unsigned i = 0; i < attrs.size(); ++i) { + unsigned val = attrs[i].attrs << 16 | attrs[i].index; + ID.AddInteger(val); + } +} + +static ManagedStatic > ParamAttrsLists; + +ParamAttrsList * +ParamAttrsList::get(const ParamAttrsVector &attrVec) { + assert(!attrVec.empty() && "Illegal to create empty ParamAttrsList"); + ParamAttrsList key(attrVec); + FoldingSetNodeID ID; + key.Profile(ID); + void *InsertPos; + ParamAttrsList* PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); + if (!PAL) { + PAL = new ParamAttrsList(attrVec); + ParamAttrsLists->InsertNode(PAL, InsertPos); + } + return PAL; +} + +ParamAttrsList::~ParamAttrsList() { + ParamAttrsLists->RemoveNode(this); +} + //===----------------------------------------------------------------------===// // Function Implementation //===----------------------------------------------------------------------===// @@ -76,11 +144,7 @@ void Argument::setParent(Function *parent) { Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) : GlobalValue(PointerType::get(Ty), Value::FunctionVal, 0, 0, Linkage, name) { - CallingConvention = 0; - BasicBlocks.setItemParent(this); - BasicBlocks.setParent(this); - ArgumentList.setItemParent(this); - ArgumentList.setParent(this); + ParamAttrs = 0; SymTab = new ValueSymbolTable(); assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy) @@ -105,8 +169,11 @@ Function::~Function() { // Delete all of the method arguments and unlink from symbol table... ArgumentList.clear(); - ArgumentList.setParent(0); delete SymTab; + + // Drop our reference to the parameter attributes, if any. + if (ParamAttrs) + ParamAttrs->dropRef(); } void Function::setParent(Module *parent) { @@ -117,6 +184,16 @@ void Function::setParent(Module *parent) { LeakDetector::removeGarbageObject(this); } +void Function::setParamAttrs(ParamAttrsList *attrs) { + if (ParamAttrs) + ParamAttrs->dropRef(); + + if (attrs) + attrs->addRef(); + + ParamAttrs = attrs; +} + const FunctionType *Function::getFunctionType() const { return cast(getType()->getElementType()); } @@ -158,21 +235,27 @@ void Function::dropAllReferences() { /// particular intrinsic functions which correspond to this value are defined in /// llvm/Intrinsics.h. /// -unsigned Function::getIntrinsicID() const { - const std::string& Name = this->getName(); - if (Name.size() < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l' +unsigned Function::getIntrinsicID(bool noAssert) const { + const ValueName *ValName = this->getValueName(); + if (!ValName) + return 0; + unsigned Len = ValName->getKeyLength(); + const char *Name = ValName->getKeyData(); + + if (Len < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l' || Name[2] != 'v' || Name[3] != 'm') return 0; // All intrinsics start with 'llvm.' - assert(Name.size() != 5 && "'llvm.' is an invalid intrinsic name!"); + 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; } -const char *Intrinsic::getName(ID id) { +std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); const char * const Table[] = { "not_intrinsic", @@ -180,26 +263,34 @@ const char *Intrinsic::getName(ID id) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_NAME_TABLE }; - return Table[id]; + if (numTys == 0) + return Table[id]; + std::string Result(Table[id]); + for (unsigned i = 0; i < numTys; ++i) + if (Tys[i]) + Result += "." + Tys[i]->getDescription(); + return Result; } -const FunctionType *Intrinsic::getType(ID id) { +const FunctionType *Intrinsic::getType(ID id, const Type **Tys, + unsigned numTys) { const Type *ResultTy = NULL; std::vector ArgTys; - std::vector Attrs; bool IsVarArg = false; #define GET_INTRINSIC_GENERATOR #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_GENERATOR - return FunctionType::get(ResultTy, ArgTys, IsVarArg, Attrs); + return FunctionType::get(ResultTy, ArgTys, IsVarArg); } -Function *Intrinsic::getDeclaration(Module *M, ID id) { +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), getType(id))); + return cast(M->getOrInsertFunction(getName(id, Tys, numTys), + getType(id, Tys, numTys))); } Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { @@ -220,11 +311,8 @@ Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { if (isa(CI->getOperand(0)->getType())) return StripPointerCasts(CI->getOperand(0)); } else if (GetElementPtrInst *GEP = dyn_cast(Ptr)) { - for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) - if (!isa(GEP->getOperand(i)) || - !cast(GEP->getOperand(i))->isNullValue()) - return Ptr; - return StripPointerCasts(GEP->getOperand(0)); + if (GEP->hasAllZeroIndices()) + return StripPointerCasts(GEP->getOperand(0)); } return Ptr; }