mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
Add support for invoke to the MemoryBuiltin analysid.
Update comments accordingly. Make instcombine remove useless invokes to C++'s 'new' allocation function (test attached). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158937 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
54c5bc8799
commit
2b3e958053
@ -31,28 +31,29 @@ class Type;
|
||||
class Value;
|
||||
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates or
|
||||
/// reallocates memory (either malloc, calloc, realloc, or strdup like).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
|
||||
/// like).
|
||||
bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
/// \brief Tests if a value is a call to a function that returns a NoAlias
|
||||
/// pointer (including malloc/calloc/strdup-like functions).
|
||||
/// \brief Tests if a value is a call or invoke to a function that returns a
|
||||
/// NoAlias pointer (including malloc/calloc/strdup-like functions).
|
||||
bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// uninitialized memory (such as malloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates uninitialized memory (such as malloc).
|
||||
bool isMallocLikeFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// zero-filled memory (such as calloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates zero-filled memory (such as calloc).
|
||||
bool isCallocLikeFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// memory (either malloc, calloc, or strdup like).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates memory (either malloc, calloc, or strdup like).
|
||||
bool isAllocLikeFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that reallocates
|
||||
/// memory (such as realloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// reallocates memory (such as realloc).
|
||||
bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
|
||||
|
||||
|
||||
|
@ -65,11 +65,17 @@ static const AllocFnsTy AllocationFnData[] = {
|
||||
static Function *getCalledFunction(const Value *V, bool LookThroughBitCast) {
|
||||
if (LookThroughBitCast)
|
||||
V = V->stripPointerCasts();
|
||||
const CallInst *CI = dyn_cast<CallInst>(V);
|
||||
if (!CI)
|
||||
|
||||
Value *I = const_cast<Value*>(V);
|
||||
CallSite CS;
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
CS = CallSite(CI);
|
||||
else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||
CS = CallSite(II);
|
||||
else
|
||||
return 0;
|
||||
|
||||
Function *Callee = CI->getCalledFunction();
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
if (!Callee || !Callee->isDeclaration())
|
||||
return 0;
|
||||
return Callee;
|
||||
@ -122,39 +128,40 @@ static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
|
||||
}
|
||||
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates or
|
||||
/// reallocates memory (either malloc, calloc, realloc, or strdup like).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
|
||||
/// like).
|
||||
bool llvm::isAllocationFn(const Value *V, bool LookThroughBitCast) {
|
||||
return getAllocationData(V, AnyAlloc, LookThroughBitCast);
|
||||
}
|
||||
|
||||
/// \brief Tests if a value is a call to a function that returns a NoAlias
|
||||
/// pointer (including malloc/calloc/strdup-like functions).
|
||||
/// \brief Tests if a value is a call or invoke to a function that returns a
|
||||
/// NoAlias pointer (including malloc/calloc/strdup-like functions).
|
||||
bool llvm::isNoAliasFn(const Value *V, bool LookThroughBitCast) {
|
||||
return isAllocLikeFn(V, LookThroughBitCast) ||
|
||||
hasNoAliasAttr(V, LookThroughBitCast);
|
||||
}
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// uninitialized memory (such as malloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates uninitialized memory (such as malloc).
|
||||
bool llvm::isMallocLikeFn(const Value *V, bool LookThroughBitCast) {
|
||||
return getAllocationData(V, MallocLike, LookThroughBitCast);
|
||||
}
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// zero-filled memory (such as calloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates zero-filled memory (such as calloc).
|
||||
bool llvm::isCallocLikeFn(const Value *V, bool LookThroughBitCast) {
|
||||
return getAllocationData(V, CallocLike, LookThroughBitCast);
|
||||
}
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that allocates
|
||||
/// memory (either malloc, calloc, or strdup like).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// allocates memory (either malloc, calloc, or strdup like).
|
||||
bool llvm::isAllocLikeFn(const Value *V, bool LookThroughBitCast) {
|
||||
return getAllocationData(V, AllocLike, LookThroughBitCast);
|
||||
}
|
||||
|
||||
/// \brief Tests if a value is a call to a library function that reallocates
|
||||
/// memory (such as realloc).
|
||||
/// \brief Tests if a value is a call or invoke to a library function that
|
||||
/// reallocates memory (such as realloc).
|
||||
bool llvm::isReallocLikeFn(const Value *V, bool LookThroughBitCast) {
|
||||
return getAllocationData(V, ReallocLike, LookThroughBitCast);
|
||||
}
|
||||
|
@ -172,8 +172,6 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
|
||||
Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
if (isFreeCall(&CI))
|
||||
return visitFree(CI);
|
||||
if (isAllocLikeFn(&CI))
|
||||
return visitMalloc(CI);
|
||||
|
||||
// If the caller function is nounwind, mark the call as nounwind, even if the
|
||||
// callee isn't.
|
||||
@ -881,6 +879,9 @@ static IntrinsicInst *FindInitTrampoline(Value *Callee) {
|
||||
// visitCallSite - Improvements for call and invoke instructions.
|
||||
//
|
||||
Instruction *InstCombiner::visitCallSite(CallSite CS) {
|
||||
if (isAllocLikeFn(CS.getInstruction()))
|
||||
return visitMalloc(*CS.getInstruction());
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// If the callee is a pointer to a function, attempt to move any casts to the
|
||||
|
@ -1167,6 +1167,10 @@ Instruction *InstCombiner::visitMalloc(Instruction &MI) {
|
||||
}
|
||||
EraseInstFromFunction(*I);
|
||||
}
|
||||
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(&MI)) {
|
||||
BranchInst::Create(II->getNormalDest(), II->getParent());
|
||||
}
|
||||
return EraseInstFromFunction(MI);
|
||||
}
|
||||
return 0;
|
||||
|
@ -2,6 +2,9 @@
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
|
||||
declare noalias i8* @malloc(i32) nounwind
|
||||
declare noalias i8* @_Znwm(i64) ; new(unsigned long)
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
declare void @__cxa_call_unexpected(i8*)
|
||||
declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
|
||||
|
||||
; CHECK: @f1
|
||||
@ -11,3 +14,24 @@ define i64 @f1() {
|
||||
; CHECK-NEXT: ret i64 4
|
||||
ret i64 %size
|
||||
}
|
||||
|
||||
|
||||
; CHECK: @f2
|
||||
define i64 @f2() nounwind uwtable ssp {
|
||||
entry:
|
||||
; CHECK: br label
|
||||
%call = invoke noalias i8* @_Znwm(i64 13)
|
||||
to label %invoke.cont unwind label %lpad
|
||||
|
||||
invoke.cont:
|
||||
; CHECK: ret i64 13
|
||||
%0 = tail call i64 @llvm.objectsize.i64(i8* %call, i1 false)
|
||||
ret i64 %0
|
||||
|
||||
lpad:
|
||||
%1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
filter [0 x i8*] zeroinitializer
|
||||
%2 = extractvalue { i8*, i32 } %1, 0
|
||||
tail call void @__cxa_call_unexpected(i8* %2) noreturn nounwind
|
||||
unreachable
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user