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.
110115AssemblyAnnotationWriter::~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
29632971void 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
50065042void 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}
0 commit comments