================ @@ -0,0 +1,114 @@ +//===-- LowerCommentStringPass.cpp - Lower Comment string metadata -------===// +// +// 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 pass processes copyright comment strings created by Clang for +// #pragma comment(copyright, ...) implementation. +// +// Clang CodeGen creates weak_odr hidden constant string globals marked with +// !loadtime_comment metadata and adds them to llvm.compiler.used. These globals +// are placed in the __loadtime_comment section for better memory layout. +// +// This pass attaches !implicit.ref metadata from every defined function to +// each copyright string global. The PowerPC AIX backend recognizes this +// metadata and emits a .ref directive, creating a relocation that prevents +// the linker from discarding the string as long as the function is kept. +// +// This pass is currently enabled for AIX targets only. +// +// Input IR (created by Clang): +// @__loadtime_comment_str_HASH = weak_odr hidden unnamed_addr constant +// [N x i8] c"Copyright\00", section "__loadtime_comment", align 1, +// !loadtime_comment !0 +// @llvm.compiler.used = appending global [1 x ptr] +// [ptr @__loadtime_comment_str_HASH], section "llvm.metadata" +// +// Output IR: +// @__loadtime_comment_str_HASH = weak_odr hidden unnamed_addr constant +// [N x i8] c"Copyright\00", section "__loadtime_comment", align 1, +// !loadtime_comment !0 +// @llvm.compiler.used = appending global [1 x ptr] +// [ptr @__loadtime_comment_str_HASH], section "llvm.metadata" +// +// define i32 @func() !implicit.ref !1 { ... } +// !1 = !{ptr @__loadtime_comment_str_HASH} +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/LowerCommentStringPass.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/TargetParser/Triple.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" + +#define DEBUG_TYPE "lower-comment-string" + +using namespace llvm; + +static cl::opt<bool> + DisableCopyrightMetadata("disable-lower-comment-string", cl::ReallyHidden, + cl::desc("Disable LowerCommentString pass."), + cl::init(false)); + +static bool isSupportedTarget(const Module &M) { + Triple T{M.getTargetTriple()}; + return T.isOSAIX(); +} + +PreservedAnalyses LowerCommentStringPass::run(Module &M, + ModuleAnalysisManager &AM) { + if (DisableCopyrightMetadata || !isSupportedTarget(M)) + return PreservedAnalyses::all(); + + LLVMContext &Ctx = M.getContext(); + + // Collect all globals marked with !loadtime_comment metadata. + SmallVector<GlobalValue *, 4> LoadTimeCommentGlobals; + for (GlobalVariable &GV : M.globals()) { + if (GV.hasMetadata("loadtime_comment")) + LoadTimeCommentGlobals.push_back(&GV); + } + + if (LoadTimeCommentGlobals.empty()) + return PreservedAnalyses::all(); + + // Add implicit.ref from every function to each loadtime comment global. + for (GlobalValue *GV : LoadTimeCommentGlobals) { + for (Function &F : M) { ---------------- w2yehia wrote:
maybe swapping the two loops is slightly more efficient? For every function, we add a bunch of implicit refs. In practice, for pragma copyright variables there will only be one so `LoadTimeCommentGlobals.size() == 1`. https://github.com/llvm/llvm-project/pull/178184 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
