//===- CalledValuePropagation.cpp - Propagate called values -----*- 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 implements a transformation that attaches !callees metadata to // indirect call sites. For a given call site, the metadata, if present, // indicates the set of functions the call site could possibly target at // run-time. This metadata is added to indirect call sites when the set of // possible targets can be determined by analysis and is known to be small. The // analysis driving the transformation is similar to constant propagation and // makes uses of the generic sparse propagation solver. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO/CalledValuePropagation.h" #include "llvm/Analysis/SparsePropagation.h" #include "llvm/Analysis/ValueLatticeUtils.h" #include "llvm/IR/Constants.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/IPO.h" usingnamespacellvm; #define DEBUG_TYPE … /// The maximum number of functions to track per lattice value. Once the number /// of functions a call site can possibly target exceeds this threshold, it's /// lattice value becomes overdefined. The number of possible lattice values is /// bounded by Ch(F, M), where F is the number of functions in the module and M /// is MaxFunctionsPerValue. As such, this value should be kept very small. We /// likely can't do anything useful for call sites with a large number of /// possible targets, anyway. static cl::opt<unsigned> MaxFunctionsPerValue( "cvp-max-functions-per-value", cl::Hidden, cl::init(4), cl::desc("The maximum number of functions to track per lattice value")); namespace { /// To enable interprocedural analysis, we assign LLVM values to the following /// groups. The register group represents SSA registers, the return group /// represents the return values of functions, and the memory group represents /// in-memory values. An LLVM Value can technically be in more than one group. /// It's necessary to distinguish these groups so we can, for example, track a /// global variable separately from the value stored at its location. enum class IPOGrouping { … }; /// Our LatticeKeys are PointerIntPairs composed of LLVM values and groupings. CVPLatticeKey; /// The lattice value type used by our custom lattice function. It holds the /// lattice state, and a set of functions. class CVPLatticeVal { … }; /// The custom lattice function used by the generic sparse propagation solver. /// It handles merging lattice values and computing new lattice values for /// constants, arguments, values returned from trackable functions, and values /// located in trackable global variables. It also computes the lattice values /// that change as a result of executing instructions. class CVPLatticeFunc : public AbstractLatticeFunction<CVPLatticeKey, CVPLatticeVal> { … }; } // namespace namespace llvm { /// A specialization of LatticeKeyInfo for CVPLatticeKeys. The generic solver /// must translate between LatticeKeys and LLVM Values when adding Values to /// its work list and inspecting the state of control-flow related values. template <> struct LatticeKeyInfo<CVPLatticeKey> { … }; } // namespace llvm static bool runCVP(Module &M) { … } PreservedAnalyses CalledValuePropagationPass::run(Module &M, ModuleAnalysisManager &) { … }