LLVM 23.0.0git
LowerCommentStringPass.cpp
Go to the documentation of this file.
1//===-- LowerCommentStringPass.cpp - Lower Comment string metadata -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===---------------------------------------------------------------------===//
8//
9// This pass processes copyright comment strings created by Clang for
10// #pragma comment(copyright, ...) implementation.
11//
12// Clang CodeGen creates weak_odr hidden constant string globals marked with
13// !loadtime_comment metadata and adds them to llvm.compiler.used. These globals
14// are placed in the __loadtime_comment section for better memory layout.
15//
16// This pass attaches !implicit.ref metadata from every defined function to
17// each copyright string global. The PowerPC AIX backend recognizes this
18// metadata and emits a .ref directive, creating a relocation that prevents
19// the linker from discarding the string as long as the function is kept.
20//
21// This pass is currently enabled for AIX targets only.
22//
23// Input IR (created by Clang):
24// @__loadtime_comment_str_HASH = weak_odr hidden unnamed_addr constant
25// [N x i8] c"Copyright\00", section "__loadtime_comment", align 1,
26// !loadtime_comment !0
27// @llvm.compiler.used = appending global [1 x ptr]
28// [ptr @__loadtime_comment_str_HASH], section "llvm.metadata"
29//
30// Output IR:
31// @__loadtime_comment_str_HASH = weak_odr hidden unnamed_addr constant
32// [N x i8] c"Copyright\00", section "__loadtime_comment", align 1,
33// !loadtime_comment !0
34// @llvm.compiler.used = appending global [1 x ptr]
35// [ptr @__loadtime_comment_str_HASH], section "llvm.metadata"
36//
37// define i32 @func() !implicit.ref !1 { ... }
38// !1 = !{ptr @__loadtime_comment_str_HASH}
39//
40//===----------------------------------------------------------------------===//
41
43
45#include "llvm/ADT/StringRef.h"
46#include "llvm/IR/Attributes.h"
48#include "llvm/IR/Function.h"
49#include "llvm/IR/GlobalValue.h"
51#include "llvm/IR/MDBuilder.h"
52#include "llvm/IR/Metadata.h"
53#include "llvm/IR/Module.h"
54#include "llvm/IR/Type.h"
55#include "llvm/IR/Value.h"
57#include "llvm/Support/Debug.h"
60
61#define DEBUG_TYPE "lower-comment-string"
62
63using namespace llvm;
64
65static cl::opt<bool>
66 DisableCopyrightMetadata("disable-lower-comment-string", cl::ReallyHidden,
67 cl::desc("Disable LowerCommentString pass."),
68 cl::init(false));
69
70static bool isSupportedTarget(const Module &M) {
71 Triple T{M.getTargetTriple()};
72 return T.isOSAIX();
73}
74
79
80 LLVMContext &Ctx = M.getContext();
81
82 // Collect all globals marked with !loadtime_comment metadata.
83 SmallVector<GlobalValue *, 4> LoadTimeCommentGlobals;
84 for (GlobalVariable &GV : M.globals()) {
85 if (GV.hasMetadata("loadtime_comment"))
86 LoadTimeCommentGlobals.push_back(&GV);
87 }
88
89 if (LoadTimeCommentGlobals.empty())
91
92 // Add implicit.ref from every function to each loadtime comment global.
93 for (Function &F : M) {
94 if (F.isDeclaration())
95 continue;
96 for (GlobalValue *GV : LoadTimeCommentGlobals) {
98 MDNode *NewMD = MDNode::get(Ctx, Ops);
99 F.addMetadata(LLVMContext::MD_implicit_ref, *NewMD);
100
102 dbgs() << "[loadtime-comment] attached implicit.ref to function: "
103 << F.getName() << " for global: " << GV->getName() << "\n");
104 }
105 }
106
107 LLVM_DEBUG(dbgs() << "[loadtime-comment] processed "
108 << LoadTimeCommentGlobals.size()
109 << " loadtime comment globals\n");
110
111 return PreservedAnalyses::all();
112}
This file contains the simple types necessary to represent the attributes associated with functions a...
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSupportedTarget(const Module &M)
static cl::opt< bool > DisableCopyrightMetadata("disable-lower-comment-string", cl::ReallyHidden, cl::desc("Disable LowerCommentString pass."), cl::init(false))
#define F(x, y, z)
Definition MD5.cpp:54
This file contains the declarations for metadata subclasses.
#define T
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Metadata node.
Definition Metadata.h:1069
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1561
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39