#include "llvm/LLVMContext.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/CallSite.h"
+#include "llvm/Support/InstIterator.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/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
// Argument Implementation
//===----------------------------------------------------------------------===//
-Argument::Argument(const Type *Ty, const Twine &Name, Function *Par)
+void Argument::anchor() { }
+
+Argument::Argument(Type *Ty, const Twine &Name, Function *Par)
: Value(Ty, Value::ArgumentVal) {
Parent = 0;
return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal);
}
+unsigned Argument::getParamAlignment() const {
+ assert(getType()->isPointerTy() && "Only pointers have alignments");
+ return getParent()->getParamAlignment(getArgNo()+1);
+
+}
+
/// hasNestAttr - Return true if this argument has the nest attribute on
/// it in its containing function.
bool Argument::hasNestAttr() const {
return getType()->getContext();
}
-const FunctionType *Function::getFunctionType() const {
+FunctionType *Function::getFunctionType() const {
return cast<FunctionType>(getType()->getElementType());
}
return getFunctionType()->isVarArg();
}
-const Type *Function::getReturnType() const {
+Type *Function::getReturnType() const {
return getFunctionType()->getReturnType();
}
// Function Implementation
//===----------------------------------------------------------------------===//
-Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
+Function::Function(FunctionType *Ty, LinkageTypes Linkage,
const Twine &name, Module *ParentModule)
: GlobalValue(PointerType::getUnqual(Ty),
Value::FunctionVal, 0, 0, Linkage, name) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
- !getReturnType()->isOpaqueTy() && "invalid return type");
+ "invalid return type");
SymTab = new ValueSymbolTable();
// If the function has arguments, mark them as lazily built.
void Function::BuildLazyArguments() const {
// Create the arguments vector, all arguments start out unnamed.
- const FunctionType *FT = getFunctionType();
+ FunctionType *FT = getFunctionType();
for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
assert(!FT->getParamType(i)->isVoidTy() &&
"Cannot have void typed arguments!");
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<BlockAddress>(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) {
return 0;
}
-std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) {
+std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
assert(id < num_intrinsics && "Invalid intrinsic ID!");
- const char * const Table[] = {
+ static const char * const Table[] = {
"not_intrinsic",
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_NAME_TABLE
};
- if (numTys == 0)
+ if (Tys.empty())
return Table[id];
std::string Result(Table[id]);
- for (unsigned i = 0; i < numTys; ++i) {
- if (const PointerType* PTyp = dyn_cast<PointerType>(Tys[i])) {
+ for (unsigned i = 0; i < Tys.size(); ++i) {
+ if (PointerType* PTyp = dyn_cast<PointerType>(Tys[i])) {
Result += ".p" + llvm::utostr(PTyp->getAddressSpace()) +
EVT::getEVT(PTyp->getElementType()).getEVTString();
}
return Result;
}
-const FunctionType *Intrinsic::getType(LLVMContext &Context,
- ID id, const Type **Tys,
- unsigned numTys) {
- const Type *ResultTy = NULL;
- std::vector<const Type*> ArgTys;
+FunctionType *Intrinsic::getType(LLVMContext &Context,
+ ID id, ArrayRef<Type*> Tys) {
+ Type *ResultTy = NULL;
+ SmallVector<Type*, 8> ArgTys;
bool IsVarArg = false;
#define GET_INTRINSIC_GENERATOR
}
bool Intrinsic::isOverloaded(ID id) {
- const bool OTable[] = {
- false,
#define GET_INTRINSIC_OVERLOAD_TABLE
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_OVERLOAD_TABLE
- };
- return OTable[id];
}
/// This defines the "Intrinsic::getAttributes(ID id)" method.
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_ATTRIBUTES
-Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys,
- unsigned numTys) {
+Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
// There can never be multiple globals with the same name of different types,
// because intrinsics must be a specific type.
return
- cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys),
- getType(M->getContext(),
- id, Tys, numTys)));
+ cast<Function>(M->getOrInsertFunction(getName(id, Tys),
+ getType(M->getContext(), id, Tys)));
}
// This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method.
/// 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::use_const_iterator I = use_begin(), E = use_end(); I != E; ++I) {
+ for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) {
const User *U = *I;
+ // FIXME: Check for blockaddress, which does not take the address.
if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
return PutOffender ? (*PutOffender = U, true) : true;
- CallSite CS(const_cast<Instruction*>(static_cast<const Instruction*>(U)));
+ ImmutableCallSite CS(cast<Instruction>(U));
if (!CS.isCallee(I))
return PutOffender ? (*PutOffender = U, true) : true;
}
return false;
}
+bool Function::isDefTriviallyDead() const {
+ // Check the linkage
+ if (!hasLinkOnceLinkage() && !hasLocalLinkage() &&
+ !hasAvailableExternallyLinkage())
+ return false;
+
+ // Check if the function is used by anything other than a blockaddress.
+ for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I)
+ if (!isa<BlockAddress>(*I))
+ return false;
+
+ return true;
+}
+
+/// callsFunctionThatReturnsTwice - Return true if the function has a call to
+/// setjmp or other function that gcc recognizes as "returning twice".
+bool Function::callsFunctionThatReturnsTwice() const {
+ for (const_inst_iterator
+ I = inst_begin(this), E = inst_end(this); I != E; ++I) {
+ const CallInst* callInst = dyn_cast<CallInst>(&*I);
+ if (!callInst)
+ continue;
+ if (callInst->canReturnTwice())
+ return true;
+ }
+
+ return false;
+}
+
// vim: sw=2 ai