|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|