Skip to content

Commit 6e1b7af

Browse files
committed
auto-update cc ptx_kernel
1 parent e8e75e0 commit 6e1b7af

File tree

8 files changed

+118
-19
lines changed

8 files changed

+118
-19
lines changed

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ namespace llvm {
6161
/// module is modified.
6262
bool UpgradeModuleFlags(Module &M);
6363

64+
/// Convert legacy nvvm.annotations metadata to appropriate function
65+
/// attributes.
66+
void UpgradeNVVMAnnotations(Module &M);
67+
6468
/// Convert calls to ARC runtime functions to intrinsic calls and upgrade the
6569
/// old retain release marker to new module flag format.
6670
void UpgradeARCRuntime(Module &M);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
448448
llvm::UpgradeDebugInfo(*M);
449449

450450
UpgradeModuleFlags(*M);
451+
UpgradeNVVMAnnotations(*M);
451452
UpgradeSectionAttributes(*M);
452453

453454
if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE)

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7148,6 +7148,8 @@ Error BitcodeReader::materializeModule() {
71487148

71497149
UpgradeModuleFlags(*TheModule);
71507150

7151+
UpgradeNVVMAnnotations(*TheModule);
7152+
71517153
UpgradeARCRuntime(*TheModule);
71527154

71537155
return Error::success();

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/StringSwitch.h"
1818
#include "llvm/BinaryFormat/Dwarf.h"
1919
#include "llvm/IR/AttributeMask.h"
20+
#include "llvm/IR/CallingConv.h"
2021
#include "llvm/IR/Constants.h"
2122
#include "llvm/IR/DebugInfo.h"
2223
#include "llvm/IR/DebugInfoMetadata.h"
@@ -5019,6 +5020,72 @@ bool llvm::UpgradeDebugInfo(Module &M) {
50195020
return Modified;
50205021
}
50215022

5023+
bool static upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K,
5024+
const Metadata *V) {
5025+
if (K == "kernel") {
5026+
if (!mdconst::extract<ConstantInt>(V)->isZero())
5027+
cast<Function>(GV)->setCallingConv(CallingConv::PTX_Kernel);
5028+
return true;
5029+
}
5030+
if (K == "align") {
5031+
// V is a bitfeild specifying two 16-bit values. The alignment value is
5032+
// specfied in low 16-bits, The index is specified in the high bits. For the
5033+
// index, 0 indicates the return value while higher values correspond to
5034+
// each parameter (idx = param + 1).
5035+
const uint64_t AlignIdxValuePair =
5036+
mdconst::extract<ConstantInt>(V)->getZExtValue();
5037+
const unsigned Idx = (AlignIdxValuePair >> 16);
5038+
const Align StackAlign = Align(AlignIdxValuePair & 0xFFFF);
5039+
// TODO: Skip adding the stackalign attribute for returns, for now.
5040+
if (!Idx)
5041+
return false;
5042+
cast<Function>(GV)->addAttributeAtIndex(
5043+
Idx, Attribute::getWithStackAlignment(GV->getContext(), StackAlign));
5044+
return true;
5045+
}
5046+
5047+
return false;
5048+
}
5049+
5050+
void llvm::UpgradeNVVMAnnotations(Module &M) {
5051+
NamedMDNode *NamedMD = M.getNamedMetadata("nvvm.annotations");
5052+
if (!NamedMD)
5053+
return;
5054+
5055+
SmallVector<MDNode *, 8> NewNodes;
5056+
SmallSet<const MDNode *, 8> SeenNodes;
5057+
for (MDNode *MD : NamedMD->operands()) {
5058+
if (!SeenNodes.insert(MD).second)
5059+
continue;
5060+
5061+
auto *GV = mdconst::dyn_extract_or_null<GlobalValue>(MD->getOperand(0));
5062+
if (!GV)
5063+
continue;
5064+
5065+
assert((MD->getNumOperands() % 2) == 1 && "Invalid number of operands");
5066+
5067+
SmallVector<Metadata *, 8> NewOperands{MD->getOperand(0)};
5068+
// Each nvvm.annotations metadata entry will be of the following form:
5069+
// !{ ptr @gv, !"key1", value1, !"key2", value2, ... }
5070+
// start index = 1, to skip the global variable key
5071+
// increment = 2, to skip the value for each property-value pairs
5072+
for (unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {
5073+
MDString *K = cast<MDString>(MD->getOperand(j));
5074+
const MDOperand &V = MD->getOperand(j + 1);
5075+
bool Upgraded = upgradeSingleNVVMAnnotation(GV, K->getString(), V);
5076+
if (!Upgraded)
5077+
NewOperands.append({K, V});
5078+
}
5079+
5080+
if (NewOperands.size() > 1)
5081+
NewNodes.push_back(MDNode::get(M.getContext(), NewOperands));
5082+
}
5083+
5084+
NamedMD->clearOperands();
5085+
for (MDNode *N : NewNodes)
5086+
NamedMD->addOperand(N);
5087+
}
5088+
50225089
/// This checks for objc retain release marker which should be upgraded. It
50235090
/// returns true if module is modified.
50245091
static bool upgradeRetainReleaseMarker(Module &M) {

llvm/lib/Linker/IRMover.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ Error IRLinker::linkModuleFlagsMetadata() {
12441244

12451245
// Check for module flag for updates before do anything.
12461246
UpgradeModuleFlags(*SrcM);
1247+
UpgradeNVVMAnnotations(*SrcM);
12471248

12481249
// If the destination module doesn't have module flags yet, then just copy
12491250
// over the source module's flags.

llvm/lib/Target/NVPTX/NVPTXUtilities.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -310,30 +310,21 @@ std::optional<unsigned> getMaxNReg(const Function &F) {
310310
return findOneNVVMAnnotation(&F, "maxnreg");
311311
}
312312

313-
bool isKernelFunction(const Function &F) {
314-
if (F.getCallingConv() == CallingConv::PTX_Kernel)
315-
return true;
316-
317-
if (const auto X = findOneNVVMAnnotation(&F, "kernel"))
318-
return (*X == 1);
319-
320-
return false;
321-
}
322-
323313
MaybeAlign getAlign(const Function &F, unsigned Index) {
324314
// First check the alignstack metadata
325315
if (MaybeAlign StackAlign =
326316
F.getAttributes().getAttributes(Index).getStackAlignment())
327317
return StackAlign;
328318

329-
// If that is missing, check the legacy nvvm metadata
330-
std::vector<unsigned> Vs;
331-
bool retval = findAllNVVMAnnotation(&F, "align", Vs);
332-
if (!retval)
333-
return std::nullopt;
334-
for (unsigned V : Vs)
335-
if ((V >> 16) == Index)
336-
return Align(V & 0xFFFF);
319+
// check the legacy nvvm metadata only for the return value since llvm does
320+
// not support stackalign attribute for this.
321+
if (Index == 0) {
322+
std::vector<unsigned> Vs;
323+
if (findAllNVVMAnnotation(&F, "align", Vs))
324+
for (unsigned V : Vs)
325+
if ((V >> 16) == Index)
326+
return Align(V & 0xFFFF);
327+
}
337328

338329
return std::nullopt;
339330
}

llvm/lib/Target/NVPTX/NVPTXUtilities.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "NVPTX.h"
1717
#include "llvm/ADT/StringExtras.h"
1818
#include "llvm/CodeGen/ValueTypes.h"
19+
#include "llvm/IR/CallingConv.h"
1920
#include "llvm/IR/Function.h"
2021
#include "llvm/IR/GlobalVariable.h"
2122
#include "llvm/IR/IntrinsicInst.h"
@@ -63,7 +64,11 @@ std::optional<unsigned> getClusterDimz(const Function &);
6364
std::optional<unsigned> getMaxClusterRank(const Function &);
6465
std::optional<unsigned> getMinCTASm(const Function &);
6566
std::optional<unsigned> getMaxNReg(const Function &);
66-
bool isKernelFunction(const Function &);
67+
68+
inline bool isKernelFunction(const Function &F) {
69+
return F.getCallingConv() == CallingConv::PTX_Kernel;
70+
}
71+
6772
bool isParamGridConstant(const Value &);
6873

6974
MaybeAlign getAlign(const Function &, unsigned);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2+
; RUN: opt < %s -mtriple=nvptx64-unknown-unknown -O0 -S | FileCheck %s
3+
4+
define i32 @foo(i32 %a, i32 %b) {
5+
; CHECK-LABEL: define i32 @foo(
6+
; CHECK-SAME: i32 alignstack(8) [[A:%.*]], i32 alignstack(16) [[B:%.*]]) {
7+
; CHECK-NEXT: ret i32 0
8+
;
9+
ret i32 0
10+
}
11+
12+
define i32 @bar(i32 %a, i32 %b) {
13+
; CHECK-LABEL: define ptx_kernel i32 @bar(
14+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
15+
; CHECK-NEXT: ret i32 0
16+
;
17+
ret i32 0
18+
}
19+
20+
!nvvm.annotations = !{!0, !1, !2}
21+
22+
!0 = !{ptr @foo, !"align", i32 u0x00000008, !"align", i32 u0x00010008, !"align", i32 u0x00020010}
23+
!1 = !{null, !"align", i32 u0x00000008, !"align", i32 u0x00010008, !"align", i32 u0x00020008}
24+
!2 = !{ptr @bar, !"kernel", i32 1}
25+
26+
;.
27+
; CHECK: [[META0:![0-9]+]] = !{ptr @foo, !"align", i32 8}
28+
;.

0 commit comments

Comments
 (0)