Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:42

0001 //===---- TailRecursionElimination.h ----------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file transforms calls of the current function (self recursion) followed
0010 // by a return instruction with a branch to the entry of the function, creating
0011 // a loop.  This pass also implements the following extensions to the basic
0012 // algorithm:
0013 //
0014 //  1. Trivial instructions between the call and return do not prevent the
0015 //     transformation from taking place, though currently the analysis cannot
0016 //     support moving any really useful instructions (only dead ones).
0017 //  2. This pass transforms functions that are prevented from being tail
0018 //     recursive by an associative and commutative expression to use an
0019 //     accumulator variable, thus compiling the typical naive factorial or
0020 //     'fib' implementation into efficient code.
0021 //  3. TRE is performed if the function returns void, if the return
0022 //     returns the result returned by the call, or if the function returns a
0023 //     run-time constant on all exits from the function.  It is possible, though
0024 //     unlikely, that the return returns something else (like constant 0), and
0025 //     can still be TRE'd.  It can be TRE'd if ALL OTHER return instructions in
0026 //     the function return the exact same value.
0027 //  4. If it can prove that callees do not access their caller stack frame,
0028 //     they are marked as eligible for tail call elimination (by the code
0029 //     generator).
0030 //
0031 // There are several improvements that could be made:
0032 //
0033 //  1. If the function has any alloca instructions, these instructions will be
0034 //     moved out of the entry block of the function, causing them to be
0035 //     evaluated each time through the tail recursion.  Safely keeping allocas
0036 //     in the entry block requires analysis to proves that the tail-called
0037 //     function does not read or write the stack object.
0038 //  2. Tail recursion is only performed if the call immediately precedes the
0039 //     return instruction.  It's possible that there could be a jump between
0040 //     the call and the return.
0041 //  3. There can be intervening operations between the call and the return that
0042 //     prevent the TRE from occurring.  For example, there could be GEP's and
0043 //     stores to memory that will not be read or written by the call.  This
0044 //     requires some substantial analysis (such as with DSA) to prove safe to
0045 //     move ahead of the call, but doing so could allow many more TREs to be
0046 //     performed, for example in TreeAdd/TreeAlloc from the treeadd benchmark.
0047 //  4. The algorithm we use to detect if callees access their caller stack
0048 //     frames is very primitive.
0049 //
0050 //===----------------------------------------------------------------------===//
0051 
0052 #ifndef LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H
0053 #define LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H
0054 
0055 #include "llvm/IR/PassManager.h"
0056 
0057 namespace llvm {
0058 
0059 class Function;
0060 
0061 struct TailCallElimPass : PassInfoMixin<TailCallElimPass> {
0062   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0063 };
0064 }
0065 
0066 #endif // LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H