- //===---- TailRecursionElimination.h ----------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file transforms calls of the current function (self recursion) followed 
- // by a return instruction with a branch to the entry of the function, creating 
- // a loop.  This pass also implements the following extensions to the basic 
- // algorithm: 
- // 
- //  1. Trivial instructions between the call and return do not prevent the 
- //     transformation from taking place, though currently the analysis cannot 
- //     support moving any really useful instructions (only dead ones). 
- //  2. This pass transforms functions that are prevented from being tail 
- //     recursive by an associative and commutative expression to use an 
- //     accumulator variable, thus compiling the typical naive factorial or 
- //     'fib' implementation into efficient code. 
- //  3. TRE is performed if the function returns void, if the return 
- //     returns the result returned by the call, or if the function returns a 
- //     run-time constant on all exits from the function.  It is possible, though 
- //     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 their caller stack frame, 
- //     they are marked as eligible for tail call elimination (by the code 
- //     generator). 
- // 
- // There are several improvements that could be made: 
- // 
- //  1. If the function has any alloca instructions, these instructions will be 
- //     moved out of the entry block of the function, causing them to be 
- //     evaluated each time through the tail recursion.  Safely keeping allocas 
- //     in the entry block requires analysis to proves that the tail-called 
- //     function does not read or write the stack object. 
- //  2. Tail recursion is only performed if the call immediately precedes the 
- //     return instruction.  It's possible that there could be a jump between 
- //     the call and the return. 
- //  3. There can be intervening operations between the call and the return that 
- //     prevent the TRE from occurring.  For example, there could be GEP's and 
- //     stores to memory that will not be read or written by the call.  This 
- //     requires some substantial analysis (such as with DSA) to prove safe to 
- //     move ahead of the call, but doing so could allow many more TREs to be 
- //     performed, for example in TreeAdd/TreeAlloc from the treeadd benchmark. 
- //  4. The algorithm we use to detect if callees access their caller stack 
- //     frames is very primitive. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H 
- #define LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H 
-   
- #include "llvm/IR/PassManager.h" 
-   
- namespace llvm { 
-   
- class Function; 
-   
- struct TailCallElimPass : PassInfoMixin<TailCallElimPass> { 
-   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 
- }; 
- } 
-   
- #endif // LLVM_TRANSFORMS_SCALAR_TAILRECURSIONELIMINATION_H 
-