Skip to content

Commit 203c7e3

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 cdc8e8d commit 203c7e3

File tree

10 files changed

+288
-15
lines changed

10 files changed

+288
-15
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: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2871,7 +2871,14 @@ foreach sp = [0, 1] in {
28712871
defvar nargs = !size(args);
28722872
defvar scale_d_imm = ArgIndex<!sub(nargs, 1)>;
28732873
defvar scale_d_imm_range = [ImmArg<scale_d_imm>, Range<scale_d_imm, 0, 16>];
2874-
defvar intrinsic_properties = !listconcat(
2874+
2875+
// Check if this is the specific llvm.nvvm.tcgen05.mma.tensor intrinsic.
2876+
defvar is_target_intrinsic = !and(!eq(sp, 0),
2877+
!eq(space, "tensor"),
2878+
!eq(scale_d, 0),
2879+
!eq(ashift, 0));
2880+
2881+
defvar base_properties = !listconcat(
28752882
mma.common_intr_props,
28762883
!if(!eq(scale_d, 1), scale_d_imm_range, []),
28772884
[Range<ArgIndex<nargs>, 0, !if(!eq(scale_d, 1), 2, 4)>, // kind
@@ -2881,6 +2888,13 @@ foreach sp = [0, 1] in {
28812888
]
28822889
);
28832890

2891+
defvar intrinsic_properties = !if(is_target_intrinsic,
2892+
!listconcat(base_properties,
2893+
[ArgInfo<ArgIndex<nargs>, "kind", "printTcgen05MMAKind">,
2894+
ArgInfo<ArgIndex<!add(nargs, 1)>, "cta_group">,
2895+
ArgInfo<ArgIndex<!add(nargs, 2)>, "collector", "printTcgen05CollectorUsageOp">]),
2896+
base_properties);
2897+
28842898
def mma.record:
28852899
DefaultAttrsIntrinsicFlags<[], args, flags, intrinsic_properties,
28862900
mma.intr>;

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: 44 additions & 10 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"
@@ -106,6 +107,10 @@ static cl::opt<bool> PreserveAssemblyUseListOrder(
106107
"preserve-ll-uselistorder", cl::Hidden, cl::init(false),
107108
cl::desc("Preserve use-list order when writing LLVM assembly."));
108109

110+
static cl::opt<bool> PrintFormattedIntrinsics(
111+
"print-formatted-intrinsics",
112+
cl::desc("Enable pretty print format for intrinsic arguments"));
113+
109114
// Make virtual table appear in this compilation unit.
110115
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;
111116

@@ -2841,6 +2846,7 @@ class AssemblyWriter {
28412846
SetVector<const Comdat *> Comdats;
28422847
bool IsForDebug;
28432848
bool ShouldPreserveUseListOrder;
2849+
bool PrettyPrintIntrinsicArgs;
28442850
UseListOrderMap UseListOrders;
28452851
SmallVector<StringRef, 8> MDNames;
28462852
/// Synchronization scope names registered with LLVMContext.
@@ -2946,7 +2952,8 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
29462952
ShouldPreserveUseListOrder(
29472953
PreserveAssemblyUseListOrder.getNumOccurrences()
29482954
? PreserveAssemblyUseListOrder
2949-
: ShouldPreserveUseListOrder) {
2955+
: ShouldPreserveUseListOrder),
2956+
PrettyPrintIntrinsicArgs(PrintFormattedIntrinsics) {
29502957
if (!TheModule)
29512958
return;
29522959
for (const GlobalObject &GO : TheModule->global_objects())
@@ -2958,7 +2965,8 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
29582965
const ModuleSummaryIndex *Index, bool IsForDebug)
29592966
: Out(o), TheIndex(Index), Machine(Mac), TypePrinter(/*Module=*/nullptr),
29602967
IsForDebug(IsForDebug),
2961-
ShouldPreserveUseListOrder(PreserveAssemblyUseListOrder) {}
2968+
ShouldPreserveUseListOrder(PreserveAssemblyUseListOrder),
2969+
PrettyPrintIntrinsicArgs(false) {}
29622970

29632971
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
29642972
if (!Operand) {
@@ -4575,12 +4583,40 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
45754583
Out << ' ';
45764584
writeOperand(Operand, false);
45774585
Out << '(';
4586+
bool HasPrettyPrintedArgs =
4587+
PrettyPrintIntrinsicArgs && isa<IntrinsicInst>(CI) &&
4588+
Intrinsic::hasPrettyPrintedArgs(CI->getIntrinsicID());
4589+
45784590
ListSeparator LS;
4579-
for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
4580-
Out << LS;
4581-
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttrs(op));
4582-
}
4591+
if (HasPrettyPrintedArgs) {
4592+
Function *CalledFunc = CI->getCalledFunction();
4593+
auto PrintArgComment = [&](unsigned ArgNo) {
4594+
if (!CalledFunc->hasParamAttribute(ArgNo, Attribute::ImmArg))
4595+
return;
4596+
const Constant *ConstArg = dyn_cast<Constant>(CI->getArgOperand(ArgNo));
4597+
if (!ConstArg)
4598+
return;
4599+
std::string ArgComment;
4600+
raw_string_ostream ArgCommentStream(ArgComment);
4601+
Intrinsic::ID IID = CalledFunc->getIntrinsicID();
4602+
Intrinsic::printImmArg(IID, ArgNo, ArgCommentStream, ConstArg);
4603+
if (ArgComment.empty())
4604+
return;
4605+
Out << "/* " << ArgComment << " */ ";
4606+
};
45834607

4608+
for (unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4609+
++ArgNo) {
4610+
Out << LS;
4611+
PrintArgComment(ArgNo);
4612+
writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4613+
}
4614+
} else {
4615+
for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
4616+
Out << LS;
4617+
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttrs(op));
4618+
}
4619+
}
45844620
// Emit an ellipsis if this is a musttail call in a vararg function. This
45854621
// is only to aid readability, musttail calls forward varargs by default.
45864622
if (CI->isMustTailCall() && CI->getParent() &&
@@ -5004,12 +5040,10 @@ void AssemblyWriter::printUseLists(const Function *F) {
50045040
//===----------------------------------------------------------------------===//
50055041

50065042
void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
5007-
bool ShouldPreserveUseListOrder,
5008-
bool IsForDebug) const {
5043+
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
50095044
SlotTracker SlotTable(this->getParent());
50105045
formatted_raw_ostream OS(ROS);
5011-
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW,
5012-
IsForDebug,
5046+
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW, IsForDebug,
50135047
ShouldPreserveUseListOrder);
50145048
W.printFunction(this);
50155049
}

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"
@@ -1129,3 +1136,7 @@ Intrinsic::ID Intrinsic::getDeinterleaveIntrinsicID(unsigned Factor) {
11291136
assert(Factor >= 2 && Factor <= 8 && "Unexpected factor");
11301137
return InterleaveIntrinsics[Factor - 2].Deinterleave;
11311138
}
1139+
1140+
#define GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS
1141+
#include "llvm/IR/IntrinsicImpl.inc"
1142+
#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 --print-formatted-intrinsics feature for NVPTX intrinsics
3+
; RUN: llvm-as < %s | llvm-dis --print-formatted-intrinsics | 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)

llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,14 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
441441
int64_t Lower = R->getValueAsInt("Lower");
442442
int64_t Upper = R->getValueAsInt("Upper");
443443
addArgAttribute(ArgNo, Range, Lower, Upper);
444+
} else if (R->isSubClassOf("ArgInfo")) {
445+
unsigned ArgNo = R->getValueAsInt("ArgNo");
446+
if (ArgNo < 1)
447+
PrintFatalError(R->getLoc(),
448+
"ArgInfo requires ArgNo >= 1 (0 is return value)");
449+
StringRef ArgName = R->getValueAsString("ArgName");
450+
StringRef FuncName = R->getValueAsString("FunctionName");
451+
addPrettyPrintFunction(ArgNo - 1, ArgName, FuncName);
444452
} else {
445453
llvm_unreachable("Unknown property!");
446454
}
@@ -468,3 +476,18 @@ void CodeGenIntrinsic::addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V,
468476
ArgumentAttributes.resize(Idx + 1);
469477
ArgumentAttributes[Idx].emplace_back(AK, V, V2);
470478
}
479+
480+
void CodeGenIntrinsic::addPrettyPrintFunction(unsigned ArgIdx,
481+
StringRef ArgName,
482+
StringRef FuncName) {
483+
auto It = llvm::find_if(PrettyPrintFunctions, [ArgIdx](const auto &Info) {
484+
return Info.ArgIdx == ArgIdx;
485+
});
486+
if (It != PrettyPrintFunctions.end()) {
487+
PrintFatalError(TheDef->getLoc(), "ArgInfo for argument " + Twine(ArgIdx) +
488+
" is already defined as '" +
489+
It->FuncName + "'");
490+
return;
491+
}
492+
PrettyPrintFunctions.emplace_back(ArgIdx, ArgName, FuncName);
493+
}

llvm/utils/TableGen/Basic/CodeGenIntrinsics.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,21 @@ struct CodeGenIntrinsic {
143143
}
144144
};
145145

146-
/// Vector of attributes for each argument.
147-
SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes;
146+
/// Structure to store pretty print and argument information.
147+
struct PrettyPrintArgInfo {
148+
unsigned ArgIdx;
149+
StringRef ArgName;
150+
StringRef FuncName;
151+
152+
PrettyPrintArgInfo(unsigned Idx, StringRef Name, StringRef Func)
153+
: ArgIdx(Idx), ArgName(Name), FuncName(Func) {}
154+
};
155+
156+
/// Vector that stores ArgInfo (ArgIndex, ArgName, FunctionName).
157+
SmallVector<PrettyPrintArgInfo> PrettyPrintFunctions;
148158

149-
void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0,
150-
uint64_t V2 = 0);
159+
void addPrettyPrintFunction(unsigned ArgIdx, StringRef ArgName,
160+
StringRef FuncName);
151161

152162
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
153163

0 commit comments

Comments
 (0)