//===- bolt/Passes/ValidateInternalCalls.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 // //===----------------------------------------------------------------------===// #ifndef BOLT_PASSES_VALIDATEINTERNALCALLS_H #define BOLT_PASSES_VALIDATEINTERNALCALLS_H #include "bolt/Passes/BinaryPasses.h" namespace llvm { namespace bolt { /// Post-processing for internal calls. What are those? They are call /// instructions that do not transfer control to another function, but /// rather branch to a basic block inside the caller function itself. /// This pass checks that the internal calls observed in a function are /// manageable. We support two types: /// /// 1. Position Independent Code (PIC) tricks: in this type of internal /// call, we don't really have a call because the return address is /// not utilized for branching to, but only as a base address to /// reference other objects. We call it a "trick" because this is not /// the standard way a compiler would do this and this will often come /// from awkwardly written assembly code. /// /// 2. Real internal calls: in this case, a function was inlined inside /// a caller, but the CALL instruction wasn't removed. This pair of /// caller-callee is treated as a single function and is analyzed /// here. /// /// In general, the rest of the BOLT pipeline (other optimizations, including /// code reordering) will not support neither of these cases. In this pass, /// we just identify them, verify they are safe (do not reference objects /// that will be moved after reordering) and freeze these functions in the /// way they were read. We do this by marking them as non-simple. /// /// Why do we freeze them? /// /// Type 1 is not safe to optimize because any changed offsets will break the /// PIC references made in this code. Type 2 is not safe to optimize because /// it requires BOLT to understand a new CFG format where internal calls are /// broken into two BBs (calling block and returning block), and we currently do /// not support this elsewhere. Only this pass is able to make sense of these /// non-canonical CFGs (specifically, fixBranches does not support them). /// class ValidateInternalCalls : public BinaryFunctionPass { … }; } // namespace bolt } // namespace llvm #endif