Skip to content

Commit cfa6019

Browse files
author
Tony Varghese
committed
Addressed the review comments. removed redundant tests
1 parent fbbb701 commit cfa6019

File tree

10 files changed

+90
-236
lines changed

10 files changed

+90
-236
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
13661366
def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">,
13671367
InGroup<IgnoredPragmas>;
13681368
def warn_pragma_comment_once : Warning<"'#pragma comment %0' "
1369-
"can be specified only once per source file - ignored">,
1369+
"can be specified only once per translation unit - ignored">,
13701370
InGroup<IgnoredPragmas>;
13711371
// - #pragma detect_mismatch
13721372
def err_pragma_detect_mismatch_malformed : Error<

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,11 +1556,9 @@ void CodeGenModule::Release() {
15561556
EmitBackendOptionsMetadata(getCodeGenOpts());
15571557

15581558
// Emit copyright metadata for AIX
1559-
if (!AIXCopyrightComment.empty()) {
1560-
auto *NMD =
1561-
getModule().getOrInsertNamedMetadata("aix.copyright.comment");
1562-
for (auto *MD : AIXCopyrightComment)
1563-
NMD->addOperand(MD);
1559+
if (AIXCopyrightComment) {
1560+
auto *NMD = getModule().getOrInsertNamedMetadata("aix.copyright.comment");
1561+
NMD->addOperand(AIXCopyrightComment);
15641562
}
15651563

15661564
// If there is device offloading code embed it in the host now.
@@ -3325,21 +3323,19 @@ void CodeGenModule::AddDependentLib(StringRef Lib) {
33253323
LinkerOptionsMetadata.push_back(llvm::MDNode::get(C, MDOpts));
33263324
}
33273325

3328-
/// Process the #pragma comment(copyright, " copy right string ")
3329-
/// and create llvm metadata for the copyrgiht
3326+
/// Process the #pragma comment(copyright, "copyright string ")
3327+
/// and create llvm metadata for the copyright
33303328
void CodeGenModule::ProcessPragmaCommentCopyright(StringRef Comment) {
33313329

3332-
// Pragma Comment Copyright is enabled only when:
3333-
// - OS is AIX
3334-
// - Comment is non empty
3335-
if (!getTriple().isOSAIX() || Comment.empty())
3330+
if (!getTriple().isOSAIX())
33363331
return;
33373332

33383333
// Create llvm metadata with the comment string
33393334
auto &C = getLLVMContext();
33403335
llvm::Metadata *Ops[] = {llvm::MDString::get(C, Comment.str())};
33413336
auto *Node = llvm::MDNode::get(C, Ops);
3342-
AIXCopyrightComment.push_back(Node); // This should be available during the runtime
3337+
if(!AIXCopyrightComment)
3338+
AIXCopyrightComment = Node;
33433339
}
33443340

33453341
/// Add link options implied by the given module, including modules

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,9 @@ class CodeGenModule : public CodeGenTypeCache {
587587
/// A vector of metadata strings for dependent libraries for ELF.
588588
SmallVector<llvm::MDNode *, 16> ELFDependentLibraries;
589589

590-
/// A vector of metadata strings for copyright comment for AIX
591-
SmallVector<llvm::MDNode *, 16> AIXCopyrightComment;
590+
/// Single module-level copyright comment for AIX (if any).
591+
/// We only ever accept one per TU.
592+
llvm::MDNode *AIXCopyrightComment = nullptr;
592593

593594
/// @name Cache for Objective-C runtime types
594595
/// @{
@@ -1461,7 +1462,7 @@ class CodeGenModule : public CodeGenTypeCache {
14611462
/// Appends a dependent lib to the appropriate metadata value.
14621463
void AddDependentLib(StringRef Lib);
14631464

1464-
/// Append AIX copyright comment to the module-level metadata.
1465+
/// Record the AIX copyright comment in module-level metadata.
14651466
void ProcessPragmaCommentCopyright(StringRef Comment);
14661467

14671468
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);

clang/lib/Parse/ParsePragma.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ struct PragmaCommentHandler : public PragmaHandler {
236236

237237
private:
238238
Sema &Actions;
239+
bool SeenAIXCopyright = false; // TU-scoped
239240
};
240241

241242
struct PragmaDetectMismatchHandler : public PragmaHandler {
@@ -3222,17 +3223,14 @@ void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
32223223
return;
32233224
}
32243225

3225-
// pragma comment copyright can each appear only once in a TU.
3226-
if (PP.getTargetInfo().getTriple().isOSAIX()) {
3227-
static bool SeenAIXCopyright = false;
3228-
if (Kind == PCK_Copyright) {
3226+
// On AIX, pragma comment copyright can each appear only once in a TU.
3227+
if (PP.getTargetInfo().getTriple().isOSAIX() && Kind == PCK_Copyright) {
32293228
if (SeenAIXCopyright) {
32303229
PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_once)
32313230
<< II->getName();
32323231
return;
32333232
}
32343233
SeenAIXCopyright = true;
3235-
}
32363234
}
32373235

32383236
// Read the optional string if present.

clang/test/CodeGen/PowerPC/pragma-comment-copyright-aix-multi-lto.c

Lines changed: 0 additions & 110 deletions
This file was deleted.

clang/test/CodeGen/PowerPC/pragma-comment-copyright-aix.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// REQUIRES: powerpc-registered-target, system-aix
21
// RUN: %clang_cc1 %s -triple powerpc-ibm-aix -O0 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
32
// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix -O0 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
43
// RUN: %clang_cc1 %s -triple powerpc-ibm-aix -verify
@@ -16,7 +15,7 @@
1615
#pragma comment(copyright, "@(#) Copyright")
1716

1817
// Test duplicate copyright - should warn and ignore
19-
#pragma comment(copyright, "Duplicate Copyright") // expected-warning {{'#pragma comment copyright' can be specified only once per source file - ignored}}
18+
#pragma comment(copyright, "Duplicate Copyright") // expected-warning {{'#pragma comment copyright' can be specified only once per translation unit - ignored}}
2019

2120
int main() { return 0; }
2221

llvm/include/llvm/Transforms/Utils/CopyrightMetadataPass.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,6 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// The CopyrightMetadataPass lowers the module-level metadata emitted by Clang
10-
// for `#pragma comment(copyright, "...")` on AIX:
11-
//
12-
// !aix.copyright.comment = !{!"Copyright ..."}
13-
//
14-
// into an internal constant string global that is preserved across all compiler
15-
// and linker stages. Each translation unit produces one TU-local string symbol
16-
// (`__aix_copyright_str`), and the pass attaches `!implicit.ref` metadata to
17-
// defined functions referencing this symbol. The PowerPC AIX backend recognizes
18-
// this metadata and emits `.ref` directives in the XCOFF assembly, ensuring the
19-
// copyright strings:
20-
//
21-
// • survive optimization and LTO,
22-
// • are not removed by linker garbage collection, and
23-
// • remain visible in the final binary.
24-
//
25-
//===----------------------------------------------------------------------===//
268

279
#ifndef LLVM_TRANSFORMS_UTILS_COPYRIGHTMETADATAPASS_H
2810
#define LLVM_TRANSFORMS_UTILS_COPYRIGHTMETADATAPASS_H
@@ -40,4 +22,4 @@ class CopyrightMetadataPass : public PassInfoMixin<CopyrightMetadataPass> {
4022

4123
} // namespace llvm
4224

43-
#endif // LLVM_TRANSFORMS_UTILS_WYVERN_COPYRIGHTMETADATAPASS_H
25+
#endif // LLVM_TRANSFORMS_UTILS_COPYRIGHTMETADATAPASS_H

llvm/lib/Transforms/Utils/CopyrightMetadataPass.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,22 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This pass lowers module-level copyright metadata emitted by Clang:
9+
// CopyrightMetadataPass pass lowers module-level copyright metadata emitted by
10+
// Clang:
1011
//
1112
// !aix.copyright.comment = !{!"Copyright ..."}
1213
//
1314
// into concrete, translation-unit–local globals to ensure that copyright
1415
// strings:
15-
//
16-
// • survive all optimization and LTO pipelines,
17-
// • are not removed by linker garbage collection, and
18-
// • remain visible in the final XCOFF binary.
16+
// - survive all optimization and LTO pipelines,
17+
// - are not removed by linker garbage collection, and
18+
// - remain visible in the final XCOFF binary.
1919
//
2020
// For each module (translation unit), the pass performs the following:
2121
//
2222
// 1. Creates a null-terminated, internal constant string global
23-
// (`__aix_copyright_str`) containing the copyright text.
23+
// (`__aix_copyright_str`) containing the copyright text in
24+
// `__aix_copyright` section..
2425
//
2526
// 2. Marks the string in `llvm.used` so it cannot be dropped by
2627
// optimization or LTO.
@@ -29,11 +30,25 @@
2930
// defined function in the module. The PowerPC AIX backend recognizes
3031
// this metadata and emits a `.ref` directive from the function to the
3132
// string, creating a concrete relocation that prevents the linker from
32-
// discarding it.
33+
// discarding it (as long as the referencing symbol is kept).
34+
//
35+
// Input IR:
36+
// !aix.copyright.comment = !{!"Copyright"}
37+
// Output IR:
38+
// @__aix_copyright_str = internal constant [N x i8] c"Copyright\00",
39+
// section "__aix_copyright"
40+
// @llvm.used = appending global [1 x ptr] [ptr @__aix_copyright_str]
3341
//
42+
// define i32 @func() !implicit.ref !5 { ... }
43+
// !5 = !{ptr @__aix_copyright_str}
44+
//
45+
// The copyright string is placed in the "__aix_copyright" section (mapped to
46+
// an XCOFF csect with [RO] storage class), making it easily identifiable in
47+
// object files and executables. The R_REF relocation prevents the linker
48+
// from discarding this section during garbage collection. Copyright string (if
49+
// kept by the linker) is expected to be loaded at run time.
3450
//===----------------------------------------------------------------------===//
3551

36-
3752
#include "llvm/Transforms/Utils/CopyrightMetadataPass.h"
3853

3954
#include "llvm/ADT/SmallVector.h"
@@ -44,7 +59,6 @@
4459
#include "llvm/IR/Function.h"
4560
#include "llvm/IR/GlobalValue.h"
4661
#include "llvm/IR/GlobalVariable.h"
47-
#include "llvm/IR/IRBuilder.h"
4862
#include "llvm/IR/MDBuilder.h"
4963
#include "llvm/IR/Metadata.h"
5064
#include "llvm/IR/Module.h"
@@ -60,8 +74,6 @@
6074

6175
using namespace llvm;
6276

63-
namespace llvm {
64-
6577
static cl::opt<bool>
6678
DisableCopyrightMetadata("disable-copyright-metadata", cl::ReallyHidden,
6779
cl::desc("Disable copyright metadata pass."),
@@ -106,22 +118,28 @@ PreservedAnalyses CopyrightMetadataPass::run(Module &M,
106118
/*isConstant=*/true,
107119
GlobalValue::InternalLinkage, StrInit,
108120
/*Name=*/"__aix_copyright_str");
121+
// Set unnamed_addr to allow the linker to merge identical strings
109122
StrGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
110123
StrGV->setAlignment(Align(1));
111-
StrGV->setSection("__llvm_copyright");
112-
113-
// 2. Ensure LLVM doesn't delete it (through all pipelines/LTO).
124+
// Place in the "__aix_copyright" section.
125+
// Backend maps this to an appropriate XCOFF csect (typically [RO])
126+
// The section will appear in assembly as:
127+
// .csect __aix_copyright[RO],2
128+
StrGV->setSection("__aix_copyright");
129+
130+
// 2. Add the string to llvm.used to prevent LLVM optimization/LTO passes from
131+
// removing it.
114132
appendToUsed(M, {StrGV});
115-
// appendToCompilerUsed(M, {StrGV});
116133

117134
// 3. Attach !implicit ref to every defined function
118135
// Create a metadata node pointing to the copyright string:
119136
// !N = !{ptr @__aix_copyright_str}
120137
Metadata *Ops[] = {ConstantAsMetadata::get(StrGV)};
121-
auto *ValMD = ValueAsMetadata::get(StrGV);
122138
MDNode *ImplicitRefMD = MDNode::get(Ctx, Ops);
123139

124-
auto addImplicitRef = [&](Function &F) {
140+
// Lambda to attach implicit.ref metadata to a function.
141+
// The backend will translate this into .ref assembly directives.
142+
auto AddImplicitRef = [&](Function &F) {
125143
if (F.isDeclaration())
126144
return;
127145
// Attach the implicit.ref metadata to the function
@@ -130,15 +148,13 @@ PreservedAnalyses CopyrightMetadataPass::run(Module &M,
130148
<< F.getName() << "\n");
131149
};
132150

151+
// Process all functions in the module
133152
for (Function &F : M)
134-
addImplicitRef(F);
153+
AddImplicitRef(F);
135154

136-
// Remove the original metadata since we've processed it
137-
// This prevents reprocessing if the pass runs multiple times
155+
// Cleanup the processed metadata.
138156
MD->eraseFromParent();
139157
LLVM_DEBUG(dbgs() << "[copyright] created string and anchor for module\n");
140158

141159
return PreservedAnalyses::all();
142160
}
143-
144-
} // namespace llvm

0 commit comments

Comments
 (0)