[llvm-commits] [llvm] r141204 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Function.cpp test/Transforms/TailCallElim/setjmp.ll
Rafael Espindola
rafael.espindola at gmail.com
Wed Oct 5 13:05:14 PDT 2011
Author: rafael
Date: Wed Oct 5 15:05:13 2011
New Revision: 141204
URL: http://llvm.org/viewvc/llvm-project?rev=141204&view=rev
Log:
Check for the returns_twice attribute in callsFunctionThatReturnsTwice. This
fixes PR11038, but there are still some cleanups to be done.
Modified:
llvm/trunk/include/llvm/Instructions.h
llvm/trunk/lib/VMCore/Function.cpp
llvm/trunk/test/Transforms/TailCallElim/setjmp.ll
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=141204&r1=141203&r2=141204&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Wed Oct 5 15:05:13 2011
@@ -1267,6 +1267,15 @@
else removeAttribute(~0, Attribute::NoInline);
}
+ /// @brief Return true if the call can return twice
+ bool canReturnTwice() const {
+ return paramHasAttr(~0, Attribute::ReturnsTwice);
+ }
+ void setCanReturnTwice(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::ReturnsTwice);
+ else removeAttribute(~0, Attribute::ReturnsTwice);
+ }
+
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
return paramHasAttr(~0, Attribute::ReadNone);
Modified: llvm/trunk/lib/VMCore/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=141204&r1=141203&r2=141204&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Function.cpp (original)
+++ llvm/trunk/lib/VMCore/Function.cpp Wed Oct 5 15:05:13 2011
@@ -17,6 +17,7 @@
#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"
@@ -416,7 +417,6 @@
/// FIXME: Remove after <rdar://problem/8031714> is fixed.
/// FIXME: Is the above FIXME valid?
bool Function::callsFunctionThatReturnsTwice() const {
- const Module *M = this->getParent();
static const char *ReturnsTwiceFns[] = {
"_setjmp",
"setjmp",
@@ -428,16 +428,25 @@
"getcontext"
};
- for (unsigned I = 0; I < array_lengthof(ReturnsTwiceFns); ++I)
- if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) {
- if (!Callee->use_empty())
- for (Value::const_use_iterator
- I = Callee->use_begin(), E = Callee->use_end();
- I != E; ++I)
- if (const CallInst *CI = dyn_cast<CallInst>(*I))
- if (CI->getParent()->getParent() == this)
- return true;
+ 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;
+
+ // check for known function names.
+ // FIXME: move this to clang.
+ Function *F = callInst->getCalledFunction();
+ if (!F)
+ continue;
+ StringRef Name = F->getName();
+ for (unsigned J = 0; J < array_lengthof(ReturnsTwiceFns); ++J) {
+ if (Name == ReturnsTwiceFns[J])
+ return true;
}
+ }
return false;
}
Modified: llvm/trunk/test/Transforms/TailCallElim/setjmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/TailCallElim/setjmp.ll?rev=141204&r1=141203&r2=141204&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/TailCallElim/setjmp.ll (original)
+++ llvm/trunk/test/Transforms/TailCallElim/setjmp.ll Wed Oct 5 15:05:13 2011
@@ -1,16 +1,29 @@
; RUN: opt < %s -tailcallelim -S | FileCheck %s
-; Test that we don't tail call in a functions that calls setjmp.
+; Test that we don't tail call in a functions that calls returns_twice
+; functions.
+declare void @bar()
+
+; CHECK: foo1
; CHECK-NOT: tail call void @bar()
-define void @foo(i32* %x) {
+define void @foo1(i32* %x) {
bb:
%tmp75 = tail call i32 @setjmp(i32* %x)
call void @bar()
ret void
}
-declare i32 @setjmp(i32*) returns_twice
+declare i32 @setjmp(i32*)
-declare void @bar()
+; CHECK: foo2
+; CHECK-NOT: tail call void @bar()
+
+define void @foo2(i32* %x) {
+bb:
+ %tmp75 = tail call i32 @zed2(i32* %x)
+ call void @bar()
+ ret void
+}
+declare i32 @zed2(i32*) returns_twice
More information about the llvm-commits
mailing list