Skip to content

Commit 1104388

Browse files
[LLVM-Tablegen] Pretty Printing Arguments in LLVM Intrinsics
This patch adds LLVM infrastructure to support pretty printing arguments of the intrinsics. The motivation is to increase the readability of LLVM intrinsics and facilitate easy modifications and debugging of LLVM IR. This adds a property ArgInfo<ArgIndex, "argName", "functionName"> to the intrinsic arguments that enables printing self-explanatory inline comment for the arguments. The addition of pretty print support can provide a simple, low-overhead feature that enhances usability of LLVM intrinsics without disrupting existing workflows. Link to the RFC: https://discourse.llvm.org/t/rfc-pretty-printing-immediate-arguments-in-llvm-intrinsics/88536 Signed-off-by: Dharuni R Acharya <[email protected]>
1 parent 92e1be4 commit 1104388

File tree

11 files changed

+343
-9
lines changed

11 files changed

+343
-9
lines changed

llvm/include/llvm/IR/Intrinsics.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class LLVMContext;
3030
class Module;
3131
class AttributeList;
3232
class AttributeSet;
33+
class raw_ostream;
34+
class Constant;
3335

3436
/// This namespace contains an enum with a value for every intrinsic/builtin
3537
/// function known by LLVM. The enum values are returned by
@@ -81,6 +83,9 @@ namespace Intrinsic {
8183
/// Returns true if the intrinsic can be overloaded.
8284
LLVM_ABI bool isOverloaded(ID id);
8385

86+
/// Returns true if the intrinsic has pretty printed immediate arguments.
87+
LLVM_ABI bool hasPrettyPrintedArgs(ID id);
88+
8489
/// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a
8590
/// certain target. If it is a generic intrinsic false is returned.
8691
LLVM_ABI bool isTargetIntrinsic(ID IID);
@@ -284,6 +289,10 @@ namespace Intrinsic {
284289
/// N.
285290
LLVM_ABI Intrinsic::ID getDeinterleaveIntrinsicID(unsigned Factor);
286291

292+
/// Print the argument info for the arguments with ArgInfo.
293+
LLVM_ABI void printImmArg(ID IID, unsigned ArgIdx, raw_ostream &OS,
294+
const Constant *ImmArgVal);
295+
287296
} // namespace Intrinsic
288297

289298
} // namespace llvm

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ class NoUndef<AttrIndex idx> : IntrinsicProperty {
8787
int ArgNo = idx.Value;
8888
}
8989

90+
// ArgInfo - The specified argument has an argument name and an optional argument printing
91+
// function for diagnostic output.
92+
class ArgInfo<AttrIndex idx, string argname, string funcname = ""> : IntrinsicProperty {
93+
int ArgNo = idx.Value;
94+
string ArgName = argname;
95+
string FunctionName = funcname;
96+
}
97+
9098
// NonNull - The return value or specified argument is not null.
9199
class NonNull<AttrIndex idx> : IntrinsicProperty {
92100
int ArgNo = idx.Value;

llvm/include/llvm/IR/IntrinsicsNVVM.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,14 @@ foreach sp = [0, 1] in {
28872887
defvar nargs = !size(args);
28882888
defvar scale_d_imm = ArgIndex<!sub(nargs, 1)>;
28892889
defvar scale_d_imm_range = [ImmArg<scale_d_imm>, Range<scale_d_imm, 0, 16>];
2890-
defvar intrinsic_properties = !listconcat(
2890+
2891+
// Check if this is the specific llvm.nvvm.tcgen05.mma.tensor intrinsic.
2892+
defvar is_target_intrinsic = !and(!eq(sp, 0),
2893+
!eq(space, "tensor"),
2894+
!eq(scale_d, 0),
2895+
!eq(ashift, 0));
2896+
2897+
defvar base_properties = !listconcat(
28912898
mma.common_intr_props,
28922899
!if(!eq(scale_d, 1), scale_d_imm_range, []),
28932900
[Range<ArgIndex<nargs>, 0, !if(!eq(scale_d, 1), 2, 4)>, // kind

llvm/include/llvm/IR/NVVMIntrinsicUtils.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
#include <stdint.h>
1919

2020
#include "llvm/ADT/APFloat.h"
21+
#include "llvm/ADT/APInt.h"
22+
#include "llvm/IR/Constants.h"
2123
#include "llvm/IR/Intrinsics.h"
2224
#include "llvm/IR/IntrinsicsNVPTX.h"
25+
#include "llvm/Support/raw_ostream.h"
2326

2427
namespace llvm {
2528
namespace nvvm {
@@ -659,6 +662,51 @@ inline APFloat::roundingMode GetFMARoundingMode(Intrinsic::ID IntrinsicID) {
659662
llvm_unreachable("Invalid FP instrinsic rounding mode for NVVM fma");
660663
}
661664

665+
inline void printTcgen05MMAKind(raw_ostream &OS, const Constant *ImmArgVal) {
666+
if (const ConstantInt *CI = dyn_cast<ConstantInt>(ImmArgVal)) {
667+
uint64_t Val = CI->getZExtValue();
668+
switch (static_cast<Tcgen05MMAKind>(Val)) {
669+
case Tcgen05MMAKind::F16:
670+
OS << "f16";
671+
return;
672+
case Tcgen05MMAKind::TF32:
673+
OS << "tf32";
674+
return;
675+
case Tcgen05MMAKind::F8F6F4:
676+
OS << "f8f6f4";
677+
return;
678+
case Tcgen05MMAKind::I8:
679+
OS << "i8";
680+
return;
681+
}
682+
}
683+
llvm_unreachable(
684+
"printTcgen05MMAKind called with invalid value for immediate argument");
685+
}
686+
687+
inline void printTcgen05CollectorUsageOp(raw_ostream &OS,
688+
const Constant *ImmArgVal) {
689+
if (const ConstantInt *CI = dyn_cast<ConstantInt>(ImmArgVal)) {
690+
uint64_t Val = CI->getZExtValue();
691+
switch (static_cast<Tcgen05CollectorUsageOp>(Val)) {
692+
case Tcgen05CollectorUsageOp::DISCARD:
693+
OS << "discard";
694+
return;
695+
case Tcgen05CollectorUsageOp::LASTUSE:
696+
OS << "lastuse";
697+
return;
698+
case Tcgen05CollectorUsageOp::FILL:
699+
OS << "fill";
700+
return;
701+
case Tcgen05CollectorUsageOp::USE:
702+
OS << "use";
703+
return;
704+
}
705+
}
706+
llvm_unreachable("printTcgen05CollectorUsageOp called with invalid value for "
707+
"immediate argument");
708+
}
709+
662710
} // namespace nvvm
663711
} // namespace llvm
664712
#endif // LLVM_IR_NVVMINTRINSICUTILS_H

llvm/lib/IR/AsmWriter.cpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "llvm/IR/Instruction.h"
5454
#include "llvm/IR/Instructions.h"
5555
#include "llvm/IR/IntrinsicInst.h"
56+
#include "llvm/IR/Intrinsics.h"
5657
#include "llvm/IR/LLVMContext.h"
5758
#include "llvm/IR/Metadata.h"
5859
#include "llvm/IR/Module.h"
@@ -4580,12 +4581,38 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
45804581
Out << ' ';
45814582
writeOperand(Operand, false);
45824583
Out << '(';
4584+
bool HasPrettyPrintedArgs =
4585+
isa<IntrinsicInst>(CI) &&
4586+
Intrinsic::hasPrettyPrintedArgs(CI->getIntrinsicID());
4587+
45834588
ListSeparator LS;
4584-
for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
4585-
Out << LS;
4586-
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttrs(op));
4587-
}
4589+
if (HasPrettyPrintedArgs) {
4590+
Function *CalledFunc = CI->getCalledFunction();
4591+
auto PrintArgComment = [&](unsigned ArgNo) {
4592+
const Constant *ConstArg = dyn_cast<Constant>(CI->getArgOperand(ArgNo));
4593+
if (!ConstArg)
4594+
return;
4595+
std::string ArgComment;
4596+
raw_string_ostream ArgCommentStream(ArgComment);
4597+
Intrinsic::ID IID = CalledFunc->getIntrinsicID();
4598+
Intrinsic::printImmArg(IID, ArgNo, ArgCommentStream, ConstArg);
4599+
if (ArgComment.empty())
4600+
return;
4601+
Out << "/* " << ArgComment << " */ ";
4602+
};
45884603

4604+
for (unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4605+
++ArgNo) {
4606+
Out << LS;
4607+
PrintArgComment(ArgNo);
4608+
writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4609+
}
4610+
} else {
4611+
for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
4612+
Out << LS;
4613+
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttrs(op));
4614+
}
4615+
}
45894616
// Emit an ellipsis if this is a musttail call in a vararg function. This
45904617
// is only to aid readability, musttail calls forward varargs by default.
45914618
if (CI->isMustTailCall() && CI->getParent() &&
@@ -5009,12 +5036,10 @@ void AssemblyWriter::printUseLists(const Function *F) {
50095036
//===----------------------------------------------------------------------===//
50105037

50115038
void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
5012-
bool ShouldPreserveUseListOrder,
5013-
bool IsForDebug) const {
5039+
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
50145040
SlotTracker SlotTable(this->getParent());
50155041
formatted_raw_ostream OS(ROS);
5016-
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW,
5017-
IsForDebug,
5042+
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW, IsForDebug,
50185043
ShouldPreserveUseListOrder);
50195044
W.printFunction(this);
50205045
}

llvm/lib/IR/Intrinsics.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "llvm/IR/IntrinsicsX86.h"
3333
#include "llvm/IR/IntrinsicsXCore.h"
3434
#include "llvm/IR/Module.h"
35+
#include "llvm/IR/NVVMIntrinsicUtils.h"
3536
#include "llvm/IR/Type.h"
3637

3738
using namespace llvm;
@@ -601,6 +602,12 @@ bool Intrinsic::isOverloaded(ID id) {
601602
#undef GET_INTRINSIC_OVERLOAD_TABLE
602603
}
603604

605+
bool Intrinsic::hasPrettyPrintedArgs(ID id){
606+
#define GET_INTRINSIC_PRETTY_PRINT_TABLE
607+
#include "llvm/IR/IntrinsicImpl.inc"
608+
#undef GET_INTRINSIC_PRETTY_PRINT_TABLE
609+
}
610+
604611
/// Table of per-target intrinsic name tables.
605612
#define GET_INTRINSIC_TARGET_DATA
606613
#include "llvm/IR/IntrinsicImpl.inc"
@@ -1142,3 +1149,7 @@ Intrinsic::ID Intrinsic::getDeinterleaveIntrinsicID(unsigned Factor) {
11421149
assert(Factor >= 2 && Factor <= 8 && "Unexpected factor");
11431150
return InterleaveIntrinsics[Factor - 2].Deinterleave;
11441151
}
1152+
1153+
#define GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS
1154+
#include "llvm/IR/IntrinsicImpl.inc"
1155+
#undef GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
2+
; NOTE: This sample test demonstrates the pretty print feature for NVPTX intrinsics
3+
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
4+
5+
target triple = "nvptx64-nvidia-cuda"
6+
7+
define void @tcgen05_mma_fp16_cta1(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d) {
8+
; CHECK-LABEL: define void @tcgen05_mma_fp16_cta1(
9+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f16 */ i32 0, /* cta_group= */ i32 1, /* collector=discard */ i32 0)
10+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 0, i32 1, i32 0)
11+
12+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f16 */ i32 0, /* cta_group= */ i32 1, /* collector=lastuse */ i32 1)
13+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 0, i32 1, i32 1)
14+
15+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f16 */ i32 0, /* cta_group= */ i32 1, /* collector=fill */ i32 2)
16+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 0, i32 1, i32 2)
17+
18+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f16 */ i32 0, /* cta_group= */ i32 1, /* collector=use */ i32 3)
19+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 0, i32 1, i32 3)
20+
21+
ret void
22+
}
23+
24+
define void @tcgen05_mma_f8f6f4_cta2(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d) {
25+
; CHECK-LABEL: define void @tcgen05_mma_f8f6f4_cta2(
26+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f8f6f4 */ i32 2, /* cta_group= */ i32 2, /* collector=discard */ i32 0)
27+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 2, i32 2, i32 0)
28+
29+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f8f6f4 */ i32 2, /* cta_group= */ i32 2, /* collector=lastuse */ i32 1)
30+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 2, i32 2, i32 1)
31+
32+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f8f6f4 */ i32 2, /* cta_group= */ i32 2, /* collector=fill */ i32 2)
33+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 2, i32 2, i32 2)
34+
35+
; CHECK: call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, /* kind=f8f6f4 */ i32 2, /* cta_group= */ i32 2, /* collector=use */ i32 3)
36+
call void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6) %dtmem, ptr addrspace(6) %atensor, i64 %b, i32 %idesc, i1 %enable_inp_d, i32 2, i32 2, i32 3)
37+
38+
ret void
39+
}
40+
41+
declare void @llvm.nvvm.tcgen05.mma.tensor(ptr addrspace(6), ptr addrspace(6), i64, i32, i1, i32, i32, i32)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s | FileCheck %s
2+
3+
// Test ArgInfo property for pretty-printing intrinsic arguments.
4+
// This test verifies that TableGen generates the correct pretty-printing code
5+
// for intrinsics that use the ArgInfo property.
6+
7+
include "llvm/IR/Intrinsics.td"
8+
9+
// Simple intrinsic with two arguments that have ArgInfo.
10+
def int_dummy_foo_bar : DefaultAttrsIntrinsic<
11+
[llvm_i32_ty],
12+
[llvm_i32_ty, // data
13+
llvm_i32_ty, // mode
14+
llvm_i32_ty], // stride
15+
[IntrNoMem,
16+
ImmArg<ArgIndex<1>>,
17+
ArgInfo<ArgIndex<1>, "mode", "printDummyMode">,
18+
ArgInfo<ArgIndex<2>, "stride">]>;
19+
20+
// A custom floating point add with rounding and sat mode.
21+
def int_my_fadd_f32 : DefaultAttrsIntrinsic<
22+
[llvm_float_ty],
23+
[llvm_float_ty, // a
24+
llvm_float_ty, // b
25+
llvm_i32_ty, // rounding_mode
26+
llvm_i1_ty], // saturation_mode
27+
[IntrNoMem,
28+
ImmArg<ArgIndex<2>>,
29+
ImmArg<ArgIndex<3>>,
30+
ArgInfo<ArgIndex<2>, "rounding_mode", "printRoundingMode">,
31+
ArgInfo<ArgIndex<3>, "saturation_mode">]>;
32+
33+
// CHECK: #ifdef GET_INTRINSIC_PRETTY_PRINT_TABLE
34+
// CHECK-NEXT: static constexpr uint8_t PPTable[] = {
35+
36+
// CHECK: #endif // GET_INTRINSIC_PRETTY_PRINT_TABLE
37+
38+
// CHECK: #ifdef GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS
39+
// CHECK: void Intrinsic::printImmArg(ID IID, unsigned ArgIdx, raw_ostream &OS, const Constant *ImmArgVal) {
40+
41+
// CHECK: case dummy_foo_bar:
42+
// CHECK-NEXT: switch (ArgIdx) {
43+
44+
// CHECK-NEXT: case 1:
45+
// CHECK-NEXT: OS << "mode=";
46+
// CHECK-NEXT: printDummyMode(OS, ImmArgVal);
47+
// CHECK-NEXT: return;
48+
49+
// CHECK-NEXT: case 2:
50+
// CHECK-NEXT: OS << "stride=";
51+
// CHECK-NEXT: return;
52+
53+
// CHECK-NEXT: }
54+
// CHECK-NEXT: break;
55+
56+
// CHECK: case my_fadd_f32:
57+
// CHECK-NEXT: switch (ArgIdx) {
58+
59+
// CHECK-NEXT: case 2:
60+
// CHECK-NEXT: OS << "rounding_mode=";
61+
// CHECK-NEXT: printRoundingMode(OS, ImmArgVal);
62+
// CHECK-NEXT: return;
63+
64+
// CHECK-NEXT: case 3:
65+
// CHECK-NEXT: OS << "saturation_mode=";
66+
// CHECK-NEXT: return;
67+
68+
// CHECK-NEXT: }
69+
// CHECK-NEXT: break;
70+
71+
// CHECK: #endif // GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS

llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
447447
int64_t Lower = R->getValueAsInt("Lower");
448448
int64_t Upper = R->getValueAsInt("Upper");
449449
addArgAttribute(ArgNo, Range, Lower, Upper);
450+
} else if (R->isSubClassOf("ArgInfo")) {
451+
unsigned ArgNo = R->getValueAsInt("ArgNo");
452+
if (ArgNo < 1)
453+
PrintFatalError(R->getLoc(),
454+
"ArgInfo requires ArgNo >= 1 (0 is return value)");
455+
StringRef ArgName = R->getValueAsString("ArgName");
456+
StringRef FuncName = R->getValueAsString("FunctionName");
457+
addPrettyPrintFunction(ArgNo - 1, ArgName, FuncName);
450458
} else {
451459
llvm_unreachable("Unknown property!");
452460
}
@@ -474,3 +482,18 @@ void CodeGenIntrinsic::addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V,
474482
ArgumentAttributes.resize(Idx + 1);
475483
ArgumentAttributes[Idx].emplace_back(AK, V, V2);
476484
}
485+
486+
void CodeGenIntrinsic::addPrettyPrintFunction(unsigned ArgIdx,
487+
StringRef ArgName,
488+
StringRef FuncName) {
489+
auto It = llvm::find_if(PrettyPrintFunctions, [ArgIdx](const auto &Info) {
490+
return Info.ArgIdx == ArgIdx;
491+
});
492+
if (It != PrettyPrintFunctions.end()) {
493+
PrintFatalError(TheDef->getLoc(), "ArgInfo for argument " + Twine(ArgIdx) +
494+
" is already defined as '" +
495+
It->FuncName + "'");
496+
return;
497+
}
498+
PrettyPrintFunctions.emplace_back(ArgIdx, ArgName, FuncName);
499+
}

llvm/utils/TableGen/Basic/CodeGenIntrinsics.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ struct CodeGenIntrinsic {
149149
void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0,
150150
uint64_t V2 = 0);
151151

152+
/// Structure to store pretty print and argument information.
153+
struct PrettyPrintArgInfo {
154+
unsigned ArgIdx;
155+
StringRef ArgName;
156+
StringRef FuncName;
157+
158+
PrettyPrintArgInfo(unsigned Idx, StringRef Name, StringRef Func)
159+
: ArgIdx(Idx), ArgName(Name), FuncName(Func) {}
160+
};
161+
162+
/// Vector that stores ArgInfo (ArgIndex, ArgName, FunctionName).
163+
SmallVector<PrettyPrintArgInfo> PrettyPrintFunctions;
164+
165+
void addPrettyPrintFunction(unsigned ArgIdx, StringRef ArgName,
166+
StringRef FuncName);
167+
152168
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
153169

154170
/// Goes through all IntrProperties that have IsDefault value set and sets

0 commit comments

Comments
 (0)