[llvm-commits] [llvm] r86349 - in /llvm/trunk: lib/Transforms/Scalar/TailRecursionElimination.cpp test/Transforms/TailCallElim/nocapture.ll
Nick Lewycky
nicholas at mxc.ca
Fri Nov 6 23:10:01 PST 2009
Author: nicholas
Date: Sat Nov 7 01:10:01 2009
New Revision: 86349
URL: http://llvm.org/viewvc/llvm-project?rev=86349&view=rev
Log:
Dust off tail recursion elimination. Fix a fixme by applying CaptureTracking
and add a .ll to demo the new capability.
Added:
llvm/trunk/test/Transforms/TailCallElim/nocapture.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=86349&r1=86348&r2=86349&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Sat Nov 7 01:10:01 2009
@@ -25,7 +25,7 @@
// unlikely, that the return returns something else (like constant 0), and
// can still be TRE'd. It can be TRE'd if ALL OTHER return instructions in
// the function return the exact same value.
-// 4. If it can prove that callees do not access theier caller stack frame,
+// 4. If it can prove that callees do not access their caller stack frame,
// they are marked as eligible for tail call elimination (by the code
// generator).
//
@@ -58,6 +58,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Support/CFG.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
@@ -75,7 +76,7 @@
private:
bool ProcessReturningBlock(ReturnInst *RI, BasicBlock *&OldEntry,
bool &TailCallsAreMarkedTail,
- std::vector<PHINode*> &ArgumentPHIs,
+ SmallVector<PHINode*, 8> &ArgumentPHIs,
bool CannotTailCallElimCallsMarkedTail);
bool CanMoveAboveCall(Instruction *I, CallInst *CI);
Value *CanTransformAccumulatorRecursion(Instruction *I, CallInst *CI);
@@ -90,17 +91,7 @@
return new TailCallElim();
}
-
-/// AllocaMightEscapeToCalls - Return true if this alloca may be accessed by
-/// callees of this function. We only do very simple analysis right now, this
-/// could be expanded in the future to use mod/ref information for particular
-/// call sites if desired.
-static bool AllocaMightEscapeToCalls(AllocaInst *AI) {
- // FIXME: do simple 'address taken' analysis.
- return true;
-}
-
-/// FunctionContainsAllocas - Scan the specified basic block for alloca
+/// CheckForEscapingAllocas - Scan the specified basic block for alloca
/// instructions. If it contains any that might be accessed by calls, return
/// true.
static bool CheckForEscapingAllocas(BasicBlock *BB,
@@ -108,7 +99,7 @@
bool RetVal = false;
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
- RetVal |= AllocaMightEscapeToCalls(AI);
+ RetVal |= PointerMayBeCaptured(AI, true);
// If this alloca is in the body of the function, or if it is a variable
// sized allocation, we cannot tail call eliminate calls marked 'tail'
@@ -127,7 +118,7 @@
BasicBlock *OldEntry = 0;
bool TailCallsAreMarkedTail = false;
- std::vector<PHINode*> ArgumentPHIs;
+ SmallVector<PHINode*, 8> ArgumentPHIs;
bool MadeChange = false;
bool FunctionContainsEscapingAllocas = false;
@@ -204,7 +195,7 @@
if (I->mayHaveSideEffects()) // This also handles volatile loads.
return false;
- if (LoadInst* L = dyn_cast<LoadInst>(I)) {
+ if (LoadInst *L = dyn_cast<LoadInst>(I)) {
// Loads may always be moved above calls without side effects.
if (CI->mayHaveSideEffects()) {
// Non-volatile loads may be moved above a call with side effects if it
@@ -265,10 +256,6 @@
Function *F = TheRI->getParent()->getParent();
Value *ReturnedValue = 0;
- // TODO: Handle multiple value ret instructions;
- if (isa<StructType>(F->getReturnType()))
- return 0;
-
for (Function::iterator BBI = F->begin(), E = F->end(); BBI != E; ++BBI)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BBI->getTerminator()))
if (RI != TheRI) {
@@ -315,7 +302,7 @@
bool TailCallElim::ProcessReturningBlock(ReturnInst *Ret, BasicBlock *&OldEntry,
bool &TailCallsAreMarkedTail,
- std::vector<PHINode*> &ArgumentPHIs,
+ SmallVector<PHINode*, 8> &ArgumentPHIs,
bool CannotTailCallElimCallsMarkedTail) {
BasicBlock *BB = Ret->getParent();
Function *F = BB->getParent();
Added: llvm/trunk/test/Transforms/TailCallElim/nocapture.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/TailCallElim/nocapture.ll?rev=86349&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/TailCallElim/nocapture.ll (added)
+++ llvm/trunk/test/Transforms/TailCallElim/nocapture.ll Sat Nov 7 01:10:01 2009
@@ -0,0 +1,24 @@
+; RUN: opt %s -tailcallelim -S | FileCheck %s
+
+declare void @use(i8* nocapture, i8* nocapture)
+
+define i8* @foo(i8* nocapture %A, i1 %cond) {
+; CHECK: tailrecurse:
+; CHECK: %A.tr = phi i8* [ %A, %0 ], [ %B, %cond_true ]
+; CHECK: %cond.tr = phi i1 [ %cond, %0 ], [ false, %cond_true ]
+ %B = alloca i8
+; CHECK: %B = alloca i8
+ br i1 %cond, label %cond_true, label %cond_false
+; CHECK: br i1 %cond.tr, label %cond_true, label %cond_false
+cond_true:
+; CHECK: cond_true:
+; CHECK: br label %tailrecurse
+ call i8* @foo(i8* %B, i1 false)
+ ret i8* null
+cond_false:
+; CHECK: cond_false
+ call void @use(i8* %A, i8* %B)
+; CHECK: tail call void @use(i8* %A.tr, i8* %B)
+ ret i8* null
+; CHECK: ret i8* null
+}
More information about the llvm-commits
mailing list