[llvm-commits] [llvm] r146851 - in /llvm/trunk: include/llvm/Analysis/CodeMetrics.h include/llvm/CodeGen/MachineFunction.h lib/Analysis/InlineCost.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/StackSlotColoring.cpp test/Transforms/Inline/inline_returns_twice.ll

Joerg Sonnenberger joerg at bec.de
Sun Dec 18 12:35:43 PST 2011


Author: joerg
Date: Sun Dec 18 14:35:43 2011
New Revision: 146851

URL: http://llvm.org/viewvc/llvm-project?rev=146851&view=rev
Log:
Allow inlining of functions with returns_twice calls, if they have the
attribute themselve.

Added:
    llvm/trunk/test/Transforms/Inline/inline_returns_twice.ll
Modified:
    llvm/trunk/include/llvm/Analysis/CodeMetrics.h
    llvm/trunk/include/llvm/CodeGen/MachineFunction.h
    llvm/trunk/lib/Analysis/InlineCost.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/CodeGen/StackSlotColoring.cpp

Modified: llvm/trunk/include/llvm/Analysis/CodeMetrics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CodeMetrics.h?rev=146851&r1=146850&r2=146851&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/CodeMetrics.h (original)
+++ llvm/trunk/include/llvm/Analysis/CodeMetrics.h Sun Dec 18 14:35:43 2011
@@ -31,8 +31,9 @@
     /// caller.
     // bool NeverInline;
 
-    // True if this function contains a call to setjmp or _setjmp
-    bool callsSetJmp;
+    // True if this function contains a call to setjmp or other functions
+    // with attribute "returns twice" without having the attribute by itself.
+    bool exposesReturnsTwice;
 
     // True if this function calls itself
     bool isRecursive;
@@ -66,7 +67,7 @@
     /// NumRets - Keep track of how many Ret instructions the block contains.
     unsigned NumRets;
 
-    CodeMetrics() : callsSetJmp(false), isRecursive(false),
+    CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
                     containsIndirectBr(false), usesDynamicAlloca(false),
                     NumInsts(0), NumBlocks(0), NumCalls(0),
                     NumInlineCandidates(0), NumVectorInsts(0),

Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=146851&r1=146850&r2=146851&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Sun Dec 18 14:35:43 2011
@@ -120,10 +120,12 @@
   /// Alignment - The alignment of the function.
   unsigned Alignment;
 
-  /// CallsSetJmp - True if the function calls setjmp or sigsetjmp. This is used
-  /// to limit optimizations which cannot reason about the control flow of
-  /// setjmp.
-  bool CallsSetJmp;
+  /// ExposesReturnsTwice - True if the function calls setjmp or related
+  /// functions with attribute "returns twice", but doesn't have
+  /// the attribute itself.
+  /// This is used to limit optimizations which cannot reason
+  /// about the control flow of such functions.
+  bool ExposesReturnsTwice;
 
   MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
   void operator=(const MachineFunction&);   // DO NOT IMPLEMENT
@@ -192,15 +194,17 @@
     if (Alignment < A) Alignment = A;
   }
 
-  /// callsSetJmp - Returns true if the function calls setjmp or sigsetjmp.
-  bool callsSetJmp() const {
-    return CallsSetJmp;
+  /// exposesReturnsTwice - Returns true if the function calls setjmp or
+  /// any other similar functions with attribute "returns twice" without
+  /// having the attribute itself.
+  bool exposesReturnsTwice() const {
+    return ExposesReturnsTwice;
   }
 
-  /// setCallsSetJmp - Set a flag that indicates if there's a call to setjmp or
-  /// sigsetjmp.
-  void setCallsSetJmp(bool B) {
-    CallsSetJmp = B;
+  /// setCallsSetJmp - Set a flag that indicates if there's a call to
+  /// a "returns twice" function.
+  void setExposesReturnsTwice(bool B) {
+    ExposesReturnsTwice = B;
   }
   
   /// getInfo - Keep track of various per-function pieces of information for

Modified: llvm/trunk/lib/Analysis/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=146851&r1=146850&r2=146851&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InlineCost.cpp (original)
+++ llvm/trunk/lib/Analysis/InlineCost.cpp Sun Dec 18 14:35:43 2011
@@ -232,10 +232,12 @@
 /// from the specified function.
 void CodeMetrics::analyzeFunction(Function *F, const TargetData *TD) {
   // If this function contains a call that "returns twice" (e.g., setjmp or
-  // _setjmp), never inline it. This is a hack because we depend on the user
-  // marking their local variables as volatile if they are live across a setjmp
-  // call, and they probably won't do this in callers.
-  callsSetJmp = F->callsFunctionThatReturnsTwice();
+  // _setjmp) and it isn't marked with "returns twice" itself, never inline it.
+  // This is a hack because we depend on the user marking their local variables
+  // as volatile if they are live across a setjmp call, and they probably
+  // won't do this in callers.
+  exposesReturnsTwice = F->callsFunctionThatReturnsTwice() &&
+    !F->hasFnAttr(Attribute::ReturnsTwice);
 
   // Look at the size of the callee.
   for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
@@ -265,7 +267,7 @@
 /// NeverInline - returns true if the function should never be inlined into
 /// any caller
 bool InlineCostAnalyzer::FunctionInfo::NeverInline() {
-  return (Metrics.callsSetJmp || Metrics.isRecursive ||
+  return (Metrics.exposesReturnsTwice || Metrics.isRecursive ||
           Metrics.containsIndirectBr);
 }
 // getSpecializationBonus - The heuristic used to determine the per-call
@@ -634,7 +636,7 @@
 
   // FIXME: If any of these three are true for the callee, the callee was
   // not inlined into the caller, so I think they're redundant here.
-  CallerMetrics.callsSetJmp |= CalleeMetrics.callsSetJmp;
+  CallerMetrics.exposesReturnsTwice |= CalleeMetrics.exposesReturnsTwice;
   CallerMetrics.isRecursive |= CalleeMetrics.isRecursive;
   CallerMetrics.containsIndirectBr |= CalleeMetrics.containsIndirectBr;
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=146851&r1=146850&r2=146851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Dec 18 14:35:43 2011
@@ -452,7 +452,7 @@
   }
 
   // Determine if there is a call to setjmp in the machine function.
-  MF->setCallsSetJmp(Fn.callsFunctionThatReturnsTwice());
+  MF->setExposesReturnsTwice(Fn.callsFunctionThatReturnsTwice());
 
   // Replace forward-declared registers with the registers containing
   // the desired value.

Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=146851&r1=146850&r2=146851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original)
+++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Sun Dec 18 14:35:43 2011
@@ -426,7 +426,7 @@
   // coloring. The stack could be modified before the longjmp is executed,
   // resulting in the wrong value being used afterwards. (See
   // <rdar://problem/8007500>.)
-  if (MF.callsSetJmp())
+  if (MF.exposesReturnsTwice())
     return false;
 
   // Gather spill slot references

Added: llvm/trunk/test/Transforms/Inline/inline_returns_twice.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/inline_returns_twice.ll?rev=146851&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/Inline/inline_returns_twice.ll (added)
+++ llvm/trunk/test/Transforms/Inline/inline_returns_twice.ll Sun Dec 18 14:35:43 2011
@@ -0,0 +1,41 @@
+; RUN: opt < %s -inline -S | FileCheck %s
+
+; Check that functions with "returns_twice" calls are only inlined,
+; if they are themselve marked as such.
+
+declare i32 @a() returns_twice
+declare i32 @b() returns_twice
+
+define i32 @f() {
+entry:
+  %call = call i32 @a() returns_twice
+  %add = add nsw i32 1, %call
+  ret i32 %add
+}
+
+define i32 @g() {
+entry:
+; CHECK: define i32 @g
+; CHECK: call i32 @f()
+; CHECK-NOT: call i32 @a()
+  %call = call i32 @f()
+  %add = add nsw i32 1, %call
+  ret i32 %add
+}
+
+define i32 @h() returns_twice {
+entry:
+  %call = call i32 @b() returns_twice
+  %add = add nsw i32 1, %call
+  ret i32 %add
+}
+
+define i32 @i() {
+entry:
+; CHECK: define i32 @i
+; CHECK: call i32 @b()
+; CHECK-NOT: call i32 @h()
+  %call = call i32 @h() returns_twice
+  %add = add nsw i32 1, %call
+  ret i32 %add
+}





More information about the llvm-commits mailing list