X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FIR%2FFunction.cpp;h=bb6bef7bd026ab2a4f276deb9f3256d7752fc128;hp=4d047f6443cabc8702240497ee5216a466673665;hb=dfa550a1761a85417d0e42c8cd17cd08e753388b;hpb=70d2ca0725b05a2d372e4dc3336e8ea350093e98 diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 4d047f6443c..bb6bef7bd02 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Function.h" +#include "LLVMContextImpl.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -83,6 +84,14 @@ bool Argument::hasByValAttr() const { hasAttribute(getArgNo()+1, Attribute::ByVal); } +/// \brief Return true if this argument has the inalloca attribute on it in +/// its containing function. +bool Argument::hasInAllocaAttr() const { + if (!getType()->isPointerTy()) return false; + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::InAlloca); +} + unsigned Argument::getParamAlignment() const { assert(getType()->isPointerTy() && "Only pointers have alignments"); return getParent()->getParamAlignment(getArgNo()+1); @@ -123,20 +132,42 @@ bool Argument::hasStructRetAttr() const { hasAttribute(1, Attribute::StructRet); } -/// addAttr - Add a Attribute to an argument -void Argument::addAttr(Attribute attr) { - AttrBuilder B(attr); +/// hasReturnedAttr - Return true if this argument has the returned attribute on +/// it in its containing function. +bool Argument::hasReturnedAttr() const { + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::Returned); +} + +/// Return true if this argument has the readonly or readnone attribute on it +/// in its containing function. +bool Argument::onlyReadsMemory() const { + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::ReadOnly) || + getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::ReadNone); +} + +/// addAttr - Add attributes to an argument. +void Argument::addAttr(AttributeSet AS) { + assert(AS.getNumSlots() <= 1 && + "Trying to add more than one attribute set to an argument!"); + AttrBuilder B(AS, AS.getSlotIndex(0)); getParent()->addAttributes(getArgNo() + 1, - AttributeSet::get(getParent()->getContext(), + AttributeSet::get(Parent->getContext(), getArgNo() + 1, B)); } -/// removeAttr - Remove a Attribute from an argument -void Argument::removeAttr(Attribute attr) { - getParent()->removeAttribute(getArgNo() + 1, attr); +/// removeAttr - Remove attributes from an argument. +void Argument::removeAttr(AttributeSet AS) { + assert(AS.getNumSlots() <= 1 && + "Trying to remove more than one attribute set from an argument!"); + AttrBuilder B(AS, AS.getSlotIndex(0)); + getParent()->removeAttributes(getArgNo() + 1, + AttributeSet::get(Parent->getContext(), + getArgNo() + 1, B)); } - //===----------------------------------------------------------------------===// // Helper Methods in Function //===----------------------------------------------------------------------===// @@ -202,6 +233,10 @@ Function::~Function() { // Remove the function from the on-the-side GC table. clearGC(); + + // Remove the intrinsicID from the Cache. + if (getValueName() && isIntrinsic()) + getContext().pImpl->IntrinsicIDCache.erase(this); } void Function::BuildLazyArguments() const { @@ -249,6 +284,9 @@ void Function::dropAllReferences() { // blockaddresses, but BasicBlock's destructor takes care of those. while (!BasicBlocks.empty()) BasicBlocks.begin()->eraseFromParent(); + + // Prefix data is stored in a side table. + setPrefixData(0); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -263,9 +301,9 @@ void Function::addAttributes(unsigned i, AttributeSet attrs) { setAttributes(PAL); } -void Function::removeAttribute(unsigned i, Attribute attrs) { +void Function::removeAttributes(unsigned i, AttributeSet attrs) { AttributeSet PAL = getAttributes(); - PAL = PAL.removeAttr(getContext(), i, attrs); + PAL = PAL.removeAttributes(getContext(), i, attrs); setAttributes(PAL); } @@ -324,6 +362,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setGC(SrcF->getGC()); else clearGC(); + if (SrcF->hasPrefixData()) + setPrefixData(SrcF->getPrefixData()); + else + setPrefixData(0); } /// getIntrinsicID - This method returns the ID number of the specified @@ -331,18 +373,35 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { /// intrinsic, or if the pointer is null. This value is always defined to be /// zero to allow easy checking for whether a function is intrinsic or not. The /// particular intrinsic functions which correspond to this value are defined in -/// llvm/Intrinsics.h. +/// llvm/Intrinsics.h. Results are cached in the LLVM context, subsequent +/// requests for the same ID return results much faster from the cache. /// unsigned Function::getIntrinsicID() const { const ValueName *ValName = this->getValueName(); if (!ValName || !isIntrinsic()) return 0; + + LLVMContextImpl::IntrinsicIDCacheTy &IntrinsicIDCache = + getContext().pImpl->IntrinsicIDCache; + if (!IntrinsicIDCache.count(this)) { + unsigned Id = lookupIntrinsicID(); + IntrinsicIDCache[this]=Id; + return Id; + } + return IntrinsicIDCache[this]; +} + +/// This private method does the actual lookup of an intrinsic ID when the query +/// could not be answered from the cache. +unsigned Function::lookupIntrinsicID() const { + const ValueName *ValName = this->getValueName(); unsigned Len = ValName->getKeyLength(); const char *Name = ValName->getKeyData(); #define GET_FUNCTION_RECOGNIZER #include "llvm/IR/Intrinsics.gen" #undef GET_FUNCTION_RECOGNIZER + return 0; } @@ -402,7 +461,9 @@ enum IIT_Info { IIT_STRUCT5 = 22, IIT_EXTEND_VEC_ARG = 23, IIT_TRUNC_VEC_ARG = 24, - IIT_ANYPTR = 25 + IIT_ANYPTR = 25, + IIT_V1 = 26, + IIT_VARARG = 27 }; @@ -416,6 +477,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, case IIT_Done: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0)); return; + case IIT_VARARG: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0)); + return; case IIT_MMX: OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0)); return; @@ -446,6 +510,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, case IIT_I64: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64)); return; + case IIT_V1: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1)); + DecodeIITType(NextElt, Infos, OutputTable); + return; case IIT_V2: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2)); DecodeIITType(NextElt, Infos, OutputTable); @@ -557,6 +625,7 @@ static Type *DecodeFixedType(ArrayRef &Infos, switch (D.Kind) { case IITDescriptor::Void: return Type::getVoidTy(Context); + case IITDescriptor::VarArg: return Type::getVoidTy(Context); case IITDescriptor::MMX: return Type::getX86_MMXTy(Context); case IITDescriptor::Metadata: return Type::getMetadataTy(Context); case IITDescriptor::Half: return Type::getHalfTy(Context); @@ -667,13 +736,39 @@ 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; } return false; } +Constant *Function::getPrefixData() const { + assert(hasPrefixData()); + const LLVMContextImpl::PrefixDataMapTy &PDMap = + getContext().pImpl->PrefixDataMap; + assert(PDMap.find(this) != PDMap.end()); + return cast(PDMap.find(this)->second->getReturnValue()); +} + +void Function::setPrefixData(Constant *PrefixData) { + if (!PrefixData && !hasPrefixData()) + return; + + unsigned SCData = getSubclassDataFromValue(); + LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap; + ReturnInst *&PDHolder = PDMap[this]; + if (PrefixData) { + if (PDHolder) + PDHolder->setOperand(0, PrefixData); + else + PDHolder = ReturnInst::Create(getContext(), PrefixData); + SCData |= 2; + } else { + delete PDHolder; + PDMap.erase(this); + SCData &= ~2; + } + setValueSubclassData(SCData); +}