using namespace llvm;
BasicBlock *ilist_traits<BasicBlock>::createSentinel() {
- BasicBlock *Ret = new BasicBlock();
+ BasicBlock *Ret = BasicBlock::Create();
// This should not be garbage monitored.
LeakDetector::removeGarbageObject(Ret);
return Ret;
/// in its containing function.
bool Argument::hasByValAttr() const {
if (!isa<PointerType>(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<PointerType>(getType())) return false;
- return getParent()->paramHasAttr(getArgNo()+1, ParamAttr::NoAlias);
+ return getParent()->paramHasAttr(getArgNo()+1, Attribute::NoAlias);
}
/// hasSRetAttr - Return true if this argument has the sret attribute on
/// it in its containing function.
bool Argument::hasStructRetAttr() const {
if (!isa<PointerType>(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);
+}
//===----------------------------------------------------------------------===//
getParent()->getFunctionList().erase(this);
}
-/// @brief Determine whether the function has the given attribute.
-bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
- return 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.getParamAlignment(i);
-}
-
-/// @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 through first
-/// pointer argument.
-bool Function::hasStructRetAttr() const {
- return paramHasAttr(1, ParamAttr::StructRet);
-}
-
//===----------------------------------------------------------------------===//
// Function Implementation
//===----------------------------------------------------------------------===//
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() {
ArgumentList.clear();
delete SymTab;
- // 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 {
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<const Function*,PooledStringPtr> *CollectorNames;
-static StringPool *CollectorNamePool;
+void Function::addAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.addAttr(i, attr);
+ setAttributes(PAL);
+}
+
+void Function::removeAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.removeAttr(i, attr);
+ setAttributes(PAL);
+}
+
+// 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<const Function*,PooledStringPtr> *GCNames;
+static StringPool *GCNamePool;
-bool Function::hasCollector() const {
- return CollectorNames && CollectorNames->count(this);
+bool Function::hasGC() const {
+ return GCNames && GCNames->count(this);
}
-const char *Function::getCollector() const {
- assert(hasCollector() && "Function has no collector");
- return *(*CollectorNames)[this];
+const char *Function::getGC() const {
+ assert(hasGC() && "Function has no collector");
+ return *(*GCNames)[this];
}
-void Function::setCollector(const char *Str) {
- if (!CollectorNamePool)
- CollectorNamePool = new StringPool();
- if (!CollectorNames)
- CollectorNames = new DenseMap<const Function*,PooledStringPtr>();
- (*CollectorNames)[this] = CollectorNamePool->intern(Str);
+void Function::setGC(const char *Str) {
+ if (!GCNamePool)
+ GCNamePool = new StringPool();
+ if (!GCNames)
+ GCNames = new DenseMap<const Function*,PooledStringPtr>();
+ (*GCNames)[this] = GCNamePool->intern(Str);
}
-void Function::clearCollector() {
- if (CollectorNames) {
- CollectorNames->erase(this);
- if (CollectorNames->empty()) {
- delete CollectorNames;
- CollectorNames = 0;
- if (CollectorNamePool->empty()) {
- delete CollectorNamePool;
- CollectorNamePool = 0;
+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<Function>(Src) && "Expected a Function!");
+ GlobalValue::copyAttributesFrom(Src);
+ const Function *SrcF = cast<Function>(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
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<PointerType>(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;
}
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
}
-PAListPtr Intrinsic::getParamAttrs(ID id) {
- ParameterAttributes Attr = ParamAttr::None;
+AttrListPtr Intrinsic::getAttributes(ID id) {
+ Attributes Attr = Attribute::None;
#define GET_INTRINSIC_ATTRIBUTES
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_ATTRIBUTES
// Intrinsics cannot throw exceptions.
- Attr |= ParamAttr::NoUnwind;
+ Attr |= Attribute::NoUnwind;
- ParamAttrsWithIndex PAWI = ParamAttrsWithIndex::get(0, Attr);
- return PAListPtr::get(&PAWI, 1);
+ AttributeWithIndex PAWI = AttributeWithIndex::get(~0, Attr);
+ return AttrListPtr::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.
- Function *F =
+ return
cast<Function>(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<ConstantExpr>(Ptr)) {
- if (CE->getOpcode() == Instruction::BitCast) {
- if (isa<PointerType>(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<BitCastInst>(Ptr)) {
- if (isa<PointerType>(CI->getOperand(0)->getType()))
- return StripPointerCasts(CI->getOperand(0));
- } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
- if (GEP->hasAllZeroIndices())
- return StripPointerCasts(GEP->getOperand(0));
- }
- return Ptr;
}
// vim: sw=2 ai