aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/Analysis.cpp
diff options
context:
space:
mode:
authorDavid L. Jones <dlj@google.com>2017-11-10 01:07:01 +0000
committerDavid L. Jones <dlj@google.com>2017-11-10 01:07:01 +0000
commitdc4b1c522910ae4fe8169afc9ee1c3c3bf24efbe (patch)
tree40f81e26e2b5278a7aa0940d3953f126abe10852 /lib/CodeGen/Analysis.cpp
parent73877b794bfef507c42b5c9f34a82d9a96604737 (diff)
parent66af8bde13a515b8d0fa76201f0d5b428187fd13 (diff)
Creating branches/google/testing and tags/google/testing/ from r317203
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/testing@317856 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Analysis.cpp')
-rw-r--r--lib/CodeGen/Analysis.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp
index 79ecc4308fe..876cca4bc7a 100644
--- a/lib/CodeGen/Analysis.cpp
+++ b/lib/CodeGen/Analysis.cpp
@@ -24,8 +24,8 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/Utils/GlobalStatus.h"
@@ -516,10 +516,9 @@ bool llvm::attributesPermitTailCall(const Function *F, const Instruction *I,
bool &ADS = AllowDifferingSizes ? *AllowDifferingSizes : DummyADS;
ADS = true;
- AttrBuilder CallerAttrs(F->getAttributes(),
- AttributeSet::ReturnIndex);
+ AttrBuilder CallerAttrs(F->getAttributes(), AttributeList::ReturnIndex);
AttrBuilder CalleeAttrs(cast<CallInst>(I)->getAttributes(),
- AttributeSet::ReturnIndex);
+ AttributeList::ReturnIndex);
// Noalias is completely benign as far as calling convention goes, it
// shouldn't affect whether the call is a tail call.
@@ -566,6 +565,24 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
return false;
const Value *RetVal = Ret->getOperand(0), *CallVal = I;
+ // Intrinsic like llvm.memcpy has no return value, but the expanded
+ // libcall may or may not have return value. On most platforms, it
+ // will be expanded as memcpy in libc, which returns the first
+ // argument. On other platforms like arm-none-eabi, memcpy may be
+ // expanded as library call without return value, like __aeabi_memcpy.
+ const CallInst *Call = cast<CallInst>(I);
+ if (Function *F = Call->getCalledFunction()) {
+ Intrinsic::ID IID = F->getIntrinsicID();
+ if (((IID == Intrinsic::memcpy &&
+ TLI.getLibcallName(RTLIB::MEMCPY) == StringRef("memcpy")) ||
+ (IID == Intrinsic::memmove &&
+ TLI.getLibcallName(RTLIB::MEMMOVE) == StringRef("memmove")) ||
+ (IID == Intrinsic::memset &&
+ TLI.getLibcallName(RTLIB::MEMSET) == StringRef("memset"))) &&
+ RetVal == Call->getArgOperand(0))
+ return true;
+ }
+
SmallVector<unsigned, 4> RetPath, CallPath;
SmallVector<CompositeType *, 4> RetSubTypes, CallSubTypes;
@@ -613,25 +630,6 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
return true;
}
-bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
- if (!GV->hasLinkOnceODRLinkage())
- return false;
-
- // We assume that anyone who sets global unnamed_addr on a non-constant knows
- // what they're doing.
- if (GV->hasGlobalUnnamedAddr())
- return true;
-
- // If it is a non constant variable, it needs to be uniqued across shared
- // objects.
- if (const GlobalVariable *Var = dyn_cast<GlobalVariable>(GV)) {
- if (!Var->isConstant())
- return false;
- }
-
- return GV->hasAtLeastLocalUnnamedAddr();
-}
-
static void collectFuncletMembers(
DenseMap<const MachineBasicBlock *, int> &FuncletMembership, int Funclet,
const MachineBasicBlock *MBB) {