summaryrefslogtreecommitdiff
path: root/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/IR/Function.cpp
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Notes
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r--lib/IR/Function.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 72090f5bac3e..a88478b89bfc 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -24,7 +24,6 @@
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
@@ -195,14 +194,19 @@ LLVMContext &Function::getContext() const {
return getType()->getContext();
}
-unsigned Function::getInstructionCount() {
+unsigned Function::getInstructionCount() const {
unsigned NumInstrs = 0;
- for (BasicBlock &BB : BasicBlocks)
+ for (const BasicBlock &BB : BasicBlocks)
NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),
BB.instructionsWithoutDebug().end());
return NumInstrs;
}
+Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage,
+ const Twine &N, Module &M) {
+ return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M);
+}
+
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
@@ -215,10 +219,19 @@ void Function::eraseFromParent() {
// Function Implementation
//===----------------------------------------------------------------------===//
-Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
- Module *ParentModule)
+static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) {
+ // If AS == -1 and we are passed a valid module pointer we place the function
+ // in the program address space. Otherwise we default to AS0.
+ if (AddrSpace == static_cast<unsigned>(-1))
+ return M ? M->getDataLayout().getProgramAddressSpace() : 0;
+ return AddrSpace;
+}
+
+Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
+ const Twine &name, Module *ParentModule)
: GlobalObject(Ty, Value::FunctionVal,
- OperandTraits<Function>::op_begin(this), 0, Linkage, name),
+ OperandTraits<Function>::op_begin(this), 0, Linkage, name,
+ computeAddrSpace(AddrSpace, ParentModule)),
NumArgs(Ty->getNumParams()) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
@@ -1243,13 +1256,13 @@ bool Function::hasAddressTaken(const User* *PutOffender) const {
const User *FU = U.getUser();
if (isa<BlockAddress>(FU))
continue;
- if (!isa<CallInst>(FU) && !isa<InvokeInst>(FU)) {
+ const auto *Call = dyn_cast<CallBase>(FU);
+ if (!Call) {
if (PutOffender)
*PutOffender = FU;
return true;
}
- ImmutableCallSite CS(cast<Instruction>(FU));
- if (!CS.isCallee(&U)) {
+ if (!Call->isCallee(&U)) {
if (PutOffender)
*PutOffender = FU;
return true;
@@ -1275,12 +1288,10 @@ bool Function::isDefTriviallyDead() const {
/// 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) {
- ImmutableCallSite CS(&*I);
- if (CS && CS.hasFnAttr(Attribute::ReturnsTwice))
- return true;
- }
+ for (const Instruction &I : instructions(this))
+ if (const auto *Call = dyn_cast<CallBase>(&I))
+ if (Call->hasFnAttr(Attribute::ReturnsTwice))
+ return true;
return false;
}