Path: blob/main/contrib/llvm-project/llvm/lib/LTO/UpdateCompilerUsed.cpp
35233 views
//==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines a helper to run the internalization part of LTO.9//10//===----------------------------------------------------------------------===//1112#include "llvm/LTO/legacy/UpdateCompilerUsed.h"13#include "llvm/Analysis/TargetLibraryInfo.h"14#include "llvm/CodeGen/TargetLowering.h"15#include "llvm/CodeGen/TargetSubtargetInfo.h"16#include "llvm/IR/Mangler.h"17#include "llvm/IR/Module.h"18#include "llvm/Target/TargetMachine.h"19#include "llvm/Transforms/Utils/ModuleUtils.h"2021using namespace llvm;2223namespace {2425// Helper class that collects AsmUsed and user supplied libcalls.26class PreserveLibCallsAndAsmUsed {27public:28PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs,29const TargetMachine &TM,30std::vector<GlobalValue *> &LLVMUsed)31: AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}3233void findInModule(Module &TheModule) {34initializeLibCalls(TheModule);35for (Function &F : TheModule)36findLibCallsAndAsm(F);37for (GlobalVariable &GV : TheModule.globals())38findLibCallsAndAsm(GV);39for (GlobalAlias &GA : TheModule.aliases())40findLibCallsAndAsm(GA);41}4243private:44// Inputs45const StringSet<> &AsmUndefinedRefs;46const TargetMachine &TM;4748// Temps49llvm::Mangler Mangler;50StringSet<> Libcalls;5152// Output53std::vector<GlobalValue *> &LLVMUsed;5455// Collect names of runtime library functions. User-defined functions with the56// same names are added to llvm.compiler.used to prevent them from being57// deleted by optimizations.58void initializeLibCalls(const Module &TheModule) {59TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));60TargetLibraryInfo TLI(TLII);6162// TargetLibraryInfo has info on C runtime library calls on the current63// target.64for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);65I != E; ++I) {66LibFunc F = static_cast<LibFunc>(I);67if (TLI.has(F))68Libcalls.insert(TLI.getName(F));69}7071SmallPtrSet<const TargetLowering *, 1> TLSet;7273for (const Function &F : TheModule) {74const TargetLowering *Lowering =75TM.getSubtargetImpl(F)->getTargetLowering();7677if (Lowering && TLSet.insert(Lowering).second)78// TargetLowering has info on library calls that CodeGen expects to be79// available, both from the C runtime and compiler-rt.80for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);81I != E; ++I)82if (const char *Name =83Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))84Libcalls.insert(Name);85}86}8788void findLibCallsAndAsm(GlobalValue &GV) {89// There are no restrictions to apply to declarations.90if (GV.isDeclaration())91return;9293// There is nothing more restrictive than private linkage.94if (GV.hasPrivateLinkage())95return;9697// Conservatively append user-supplied runtime library functions (supplied98// either directly, or via a function alias) to llvm.compiler.used. These99// could be internalized and deleted by optimizations like -globalopt,100// causing problems when later optimizations add new library calls (e.g.,101// llvm.memset => memset and printf => puts).102// Leave it to the linker to remove any dead code (e.g. with -dead_strip).103GlobalValue *FuncAliasee = nullptr;104if (isa<GlobalAlias>(GV)) {105auto *A = cast<GlobalAlias>(&GV);106FuncAliasee = dyn_cast<Function>(A->getAliasee());107}108if ((isa<Function>(GV) || FuncAliasee) && Libcalls.count(GV.getName())) {109LLVMUsed.push_back(&GV);110return;111}112113SmallString<64> Buffer;114TM.getNameWithPrefix(Buffer, &GV, Mangler);115if (AsmUndefinedRefs.count(Buffer))116LLVMUsed.push_back(&GV);117}118};119120} // namespace anonymous121122void llvm::updateCompilerUsed(Module &TheModule, const TargetMachine &TM,123const StringSet<> &AsmUndefinedRefs) {124std::vector<GlobalValue *> UsedValues;125PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)126.findInModule(TheModule);127128if (UsedValues.empty())129return;130131appendToCompilerUsed(TheModule, UsedValues);132}133134135