From 057784a263d93cf2efe84f91c336ebfd30a28268 Mon Sep 17 00:00:00 2001 From: Francis Visoiu Mistrih Date: Wed, 10 Oct 2018 17:58:09 +0000 Subject: [OptRemarks] Add library for parsing optimization remarks Add a library that parses optimization remarks (currently YAML, so based on the YAMLParser). The goal is to be able to provide tools a remark parser that is not completely dependent on YAML, in case we decide to change the format later. It exposes a C API which takes a handler that is called with the remark structure. It adds a libLLVMOptRemark.a static library, and it's used in-tree by the llvm-opt-report tool (from which the parser has been mostly moved out). Differential Revision: https://reviews.llvm.org/D52776 llvm-svn: 344162 --- llvm/tools/llvm-opt-report/OptReport.cpp | 144 ++++++++----------------------- 1 file changed, 38 insertions(+), 106 deletions(-) (limited to 'llvm/tools/llvm-opt-report/OptReport.cpp') diff --git a/llvm/tools/llvm-opt-report/OptReport.cpp b/llvm/tools/llvm-opt-report/OptReport.cpp index aa7966132c2..071f779a9e6 100644 --- a/llvm/tools/llvm-opt-report/OptReport.cpp +++ b/llvm/tools/llvm-opt-report/OptReport.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/WithColor.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" +#include "llvm-c/OptRemarks.h" #include #include #include @@ -142,104 +143,44 @@ typedef std::map>>> LocationInfoTy; } // anonymous namespace -static void collectLocationInfo(yaml::Stream &Stream, - LocationInfoTy &LocationInfo) { - SmallVector Tmp; - - // Note: We're using the YAML parser here directly, instead of using the - // YAMLTraits implementation, because the YAMLTraits implementation does not - // support a way to handle only a subset of the input keys (it will error out - // if there is an input key that you don't map to your class), and - // furthermore, it does not provide a way to handle the Args sequence of - // key/value pairs, where the order must be captured and the 'String' key - // might be repeated. - for (auto &Doc : Stream) { - auto *Root = dyn_cast(Doc.getRoot()); - if (!Root) - continue; +static bool readLocationInfo(LocationInfoTy &LocationInfo) { + ErrorOr> Buf = + MemoryBuffer::getFile(InputFileName.c_str()); + if (std::error_code EC = Buf.getError()) { + WithColor::error() << "Can't open file " << InputFileName << ": " + << EC.message() << "\n"; + return false; + } - bool Transformed = Root->getRawTag() == "!Passed"; - std::string Pass, File, Function; - int Line = 0, Column = 1; + StringRef Buffer = (*Buf)->getBuffer(); + LLVMOptRemarkParserRef Parser = + LLVMOptRemarkParserCreate(Buffer.data(), Buffer.size()); + + LLVMOptRemarkEntry *Remark = nullptr; + while ((Remark = LLVMOptRemarkParserGetNext(Parser))) { + bool Transformed = + StringRef(Remark->RemarkType.Str, Remark->RemarkType.Len) == "!Passed"; + StringRef Pass(Remark->PassName.Str, Remark->PassName.Len); + StringRef File(Remark->DebugLoc.SourceFile.Str, + Remark->DebugLoc.SourceFile.Len); + StringRef Function(Remark->FunctionName.Str, Remark->FunctionName.Len); + uint32_t Line = Remark->DebugLoc.SourceLineNumber; + uint32_t Column = Remark->DebugLoc.SourceColumnNumber; + ArrayRef Args(Remark->Args, Remark->NumArgs); int VectorizationFactor = 1; int InterleaveCount = 1; int UnrollCount = 1; - for (auto &RootChild : *Root) { - auto *Key = dyn_cast(RootChild.getKey()); - if (!Key) - continue; - StringRef KeyName = Key->getValue(Tmp); - if (KeyName == "Pass") { - auto *Value = dyn_cast(RootChild.getValue()); - if (!Value) - continue; - Pass = Value->getValue(Tmp); - } else if (KeyName == "Function") { - auto *Value = dyn_cast(RootChild.getValue()); - if (!Value) - continue; - Function = Value->getValue(Tmp); - } else if (KeyName == "DebugLoc") { - auto *DebugLoc = dyn_cast(RootChild.getValue()); - if (!DebugLoc) - continue; - - for (auto &DLChild : *DebugLoc) { - auto *DLKey = dyn_cast(DLChild.getKey()); - if (!DLKey) - continue; - StringRef DLKeyName = DLKey->getValue(Tmp); - if (DLKeyName == "File") { - auto *Value = dyn_cast(DLChild.getValue()); - if (!Value) - continue; - File = Value->getValue(Tmp); - } else if (DLKeyName == "Line") { - auto *Value = dyn_cast(DLChild.getValue()); - if (!Value) - continue; - Value->getValue(Tmp).getAsInteger(10, Line); - } else if (DLKeyName == "Column") { - auto *Value = dyn_cast(DLChild.getValue()); - if (!Value) - continue; - Value->getValue(Tmp).getAsInteger(10, Column); - } - } - } else if (KeyName == "Args") { - auto *Args = dyn_cast(RootChild.getValue()); - if (!Args) - continue; - for (auto &ArgChild : *Args) { - auto *ArgMap = dyn_cast(&ArgChild); - if (!ArgMap) - continue; - for (auto &ArgKV : *ArgMap) { - auto *ArgKey = dyn_cast(ArgKV.getKey()); - if (!ArgKey) - continue; - StringRef ArgKeyName = ArgKey->getValue(Tmp); - if (ArgKeyName == "VectorizationFactor") { - auto *Value = dyn_cast(ArgKV.getValue()); - if (!Value) - continue; - Value->getValue(Tmp).getAsInteger(10, VectorizationFactor); - } else if (ArgKeyName == "InterleaveCount") { - auto *Value = dyn_cast(ArgKV.getValue()); - if (!Value) - continue; - Value->getValue(Tmp).getAsInteger(10, InterleaveCount); - } else if (ArgKeyName == "UnrollCount") { - auto *Value = dyn_cast(ArgKV.getValue()); - if (!Value) - continue; - Value->getValue(Tmp).getAsInteger(10, UnrollCount); - } - } - } - } + for (const LLVMOptRemarkArg &Arg : Args) { + StringRef ArgKeyName(Arg.Key.Str, Arg.Key.Len); + StringRef ArgValue(Arg.Value.Str, Arg.Value.Len); + if (ArgKeyName == "VectorizationFactor") + ArgValue.getAsInteger(10, VectorizationFactor); + else if (ArgKeyName == "InterleaveCount") + ArgValue.getAsInteger(10, InterleaveCount); + else if (ArgKeyName == "UnrollCount") + ArgValue.getAsInteger(10, UnrollCount); } if (Line < 1 || File.empty()) @@ -268,22 +209,13 @@ static void collectLocationInfo(yaml::Stream &Stream, UpdateLLII(LI.Vectorized); } } -} - -static bool readLocationInfo(LocationInfoTy &LocationInfo) { - ErrorOr> Buf = - MemoryBuffer::getFileOrSTDIN(InputFileName); - if (std::error_code EC = Buf.getError()) { - WithColor::error() << "Can't open file " << InputFileName << ": " - << EC.message() << "\n"; - return false; - } - SourceMgr SM; - yaml::Stream Stream(Buf.get()->getBuffer(), SM); - collectLocationInfo(Stream, LocationInfo); + bool HasError = LLVMOptRemarkParserHasError(Parser); + if (HasError) + WithColor::error() << LLVMOptRemarkParserGetErrorMessage(Parser) << "\n"; - return true; + LLVMOptRemarkParserDispose(Parser); + return !HasError; } static bool writeReport(LocationInfoTy &LocationInfo) { -- cgit v1.2.3