1*5f757f3fSDimitry Andric //===- RemarkConvert.cpp -------------------------------------------------===// 2*5f757f3fSDimitry Andric // 3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5f757f3fSDimitry Andric // 7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 8*5f757f3fSDimitry Andric // 9*5f757f3fSDimitry Andric // Convert remarks from bitstream to yaml and the other way around. 10*5f757f3fSDimitry Andric // 11*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 12*5f757f3fSDimitry Andric 13*5f757f3fSDimitry Andric #include "RemarkUtilHelpers.h" 14*5f757f3fSDimitry Andric #include "RemarkUtilRegistry.h" 15*5f757f3fSDimitry Andric 16*5f757f3fSDimitry Andric using namespace llvm; 17*5f757f3fSDimitry Andric using namespace remarks; 18*5f757f3fSDimitry Andric using namespace llvm::remarkutil; 19*5f757f3fSDimitry Andric 20*5f757f3fSDimitry Andric extern ExitOnError ExitOnErr; 21*5f757f3fSDimitry Andric static cl::SubCommand 22*5f757f3fSDimitry Andric YAML2Bitstream("yaml2bitstream", 23*5f757f3fSDimitry Andric "Convert YAML remarks to bitstream remarks"); 24*5f757f3fSDimitry Andric static cl::SubCommand 25*5f757f3fSDimitry Andric Bitstream2YAML("bitstream2yaml", 26*5f757f3fSDimitry Andric "Convert bitstream remarks to YAML remarks"); 27*5f757f3fSDimitry Andric 28*5f757f3fSDimitry Andric namespace yaml2bitstream { 29*5f757f3fSDimitry Andric /// Remark format to parse. 30*5f757f3fSDimitry Andric static constexpr Format InputFormat = Format::YAML; 31*5f757f3fSDimitry Andric /// Remark format to output. 32*5f757f3fSDimitry Andric static constexpr Format OutputFormat = Format::Bitstream; 33*5f757f3fSDimitry Andric INPUT_OUTPUT_COMMAND_LINE_OPTIONS(YAML2Bitstream) 34*5f757f3fSDimitry Andric } // namespace yaml2bitstream 35*5f757f3fSDimitry Andric 36*5f757f3fSDimitry Andric namespace bitstream2yaml { 37*5f757f3fSDimitry Andric /// Remark format to parse. 38*5f757f3fSDimitry Andric static constexpr Format InputFormat = Format::Bitstream; 39*5f757f3fSDimitry Andric /// Remark format to output. 40*5f757f3fSDimitry Andric static constexpr Format OutputFormat = Format::YAML; 41*5f757f3fSDimitry Andric INPUT_OUTPUT_COMMAND_LINE_OPTIONS(Bitstream2YAML) 42*5f757f3fSDimitry Andric } // namespace bitstream2yaml 43*5f757f3fSDimitry Andric 44*5f757f3fSDimitry Andric namespace yaml2bitstream { 45*5f757f3fSDimitry Andric /// Parses all remarks in the input YAML file. 46*5f757f3fSDimitry Andric /// \p [out] ParsedRemarks - Filled with remarks parsed from the input file. 47*5f757f3fSDimitry Andric /// \p [out] StrTab - A string table populated for later remark serialization. 48*5f757f3fSDimitry Andric /// \returns Error::success() if all remarks were successfully parsed, and an 49*5f757f3fSDimitry Andric /// Error otherwise. 50*5f757f3fSDimitry Andric static Error 51*5f757f3fSDimitry Andric tryParseRemarksFromYAMLFile(std::vector<std::unique_ptr<Remark>> &ParsedRemarks, 52*5f757f3fSDimitry Andric StringTable &StrTab) { 53*5f757f3fSDimitry Andric auto MaybeBuf = getInputMemoryBuffer(InputFileName); 54*5f757f3fSDimitry Andric if (!MaybeBuf) 55*5f757f3fSDimitry Andric return MaybeBuf.takeError(); 56*5f757f3fSDimitry Andric auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer()); 57*5f757f3fSDimitry Andric if (!MaybeParser) 58*5f757f3fSDimitry Andric return MaybeParser.takeError(); 59*5f757f3fSDimitry Andric auto &Parser = **MaybeParser; 60*5f757f3fSDimitry Andric auto MaybeRemark = Parser.next(); 61*5f757f3fSDimitry Andric for (; MaybeRemark; MaybeRemark = Parser.next()) { 62*5f757f3fSDimitry Andric StrTab.internalize(**MaybeRemark); 63*5f757f3fSDimitry Andric ParsedRemarks.push_back(std::move(*MaybeRemark)); 64*5f757f3fSDimitry Andric } 65*5f757f3fSDimitry Andric auto E = MaybeRemark.takeError(); 66*5f757f3fSDimitry Andric if (!E.isA<EndOfFileError>()) 67*5f757f3fSDimitry Andric return E; 68*5f757f3fSDimitry Andric consumeError(std::move(E)); 69*5f757f3fSDimitry Andric return Error::success(); 70*5f757f3fSDimitry Andric } 71*5f757f3fSDimitry Andric 72*5f757f3fSDimitry Andric /// Reserialize a list of parsed YAML remarks into bitstream remarks. 73*5f757f3fSDimitry Andric /// \p ParsedRemarks - A list of remarks. 74*5f757f3fSDimitry Andric /// \p StrTab - The string table for the remarks. 75*5f757f3fSDimitry Andric /// \returns Error::success() on success. 76*5f757f3fSDimitry Andric static Error tryReserializeYAML2Bitstream( 77*5f757f3fSDimitry Andric const std::vector<std::unique_ptr<Remark>> &ParsedRemarks, 78*5f757f3fSDimitry Andric StringTable &StrTab) { 79*5f757f3fSDimitry Andric auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat); 80*5f757f3fSDimitry Andric if (!MaybeOF) 81*5f757f3fSDimitry Andric return MaybeOF.takeError(); 82*5f757f3fSDimitry Andric auto OF = std::move(*MaybeOF); 83*5f757f3fSDimitry Andric auto MaybeSerializer = createRemarkSerializer( 84*5f757f3fSDimitry Andric OutputFormat, SerializerMode::Standalone, OF->os(), std::move(StrTab)); 85*5f757f3fSDimitry Andric if (!MaybeSerializer) 86*5f757f3fSDimitry Andric return MaybeSerializer.takeError(); 87*5f757f3fSDimitry Andric auto Serializer = std::move(*MaybeSerializer); 88*5f757f3fSDimitry Andric for (const auto &Remark : ParsedRemarks) 89*5f757f3fSDimitry Andric Serializer->emit(*Remark); 90*5f757f3fSDimitry Andric OF->keep(); 91*5f757f3fSDimitry Andric return Error::success(); 92*5f757f3fSDimitry Andric } 93*5f757f3fSDimitry Andric 94*5f757f3fSDimitry Andric /// Parse YAML remarks and reserialize as bitstream remarks. 95*5f757f3fSDimitry Andric /// \returns Error::success() on success, and an Error otherwise. 96*5f757f3fSDimitry Andric static Error tryYAML2Bitstream() { 97*5f757f3fSDimitry Andric StringTable StrTab; 98*5f757f3fSDimitry Andric std::vector<std::unique_ptr<Remark>> ParsedRemarks; 99*5f757f3fSDimitry Andric ExitOnErr(tryParseRemarksFromYAMLFile(ParsedRemarks, StrTab)); 100*5f757f3fSDimitry Andric return tryReserializeYAML2Bitstream(ParsedRemarks, StrTab); 101*5f757f3fSDimitry Andric } 102*5f757f3fSDimitry Andric } // namespace yaml2bitstream 103*5f757f3fSDimitry Andric 104*5f757f3fSDimitry Andric namespace bitstream2yaml { 105*5f757f3fSDimitry Andric /// Parse bitstream remarks and reserialize as YAML remarks. 106*5f757f3fSDimitry Andric /// \returns An Error if reserialization fails, or Error::success() on success. 107*5f757f3fSDimitry Andric static Error tryBitstream2YAML() { 108*5f757f3fSDimitry Andric // Create the serializer. 109*5f757f3fSDimitry Andric auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat); 110*5f757f3fSDimitry Andric if (!MaybeOF) 111*5f757f3fSDimitry Andric return MaybeOF.takeError(); 112*5f757f3fSDimitry Andric auto OF = std::move(*MaybeOF); 113*5f757f3fSDimitry Andric auto MaybeSerializer = createRemarkSerializer( 114*5f757f3fSDimitry Andric OutputFormat, SerializerMode::Standalone, OF->os()); 115*5f757f3fSDimitry Andric if (!MaybeSerializer) 116*5f757f3fSDimitry Andric return MaybeSerializer.takeError(); 117*5f757f3fSDimitry Andric 118*5f757f3fSDimitry Andric // Create the parser. 119*5f757f3fSDimitry Andric auto MaybeBuf = getInputMemoryBuffer(InputFileName); 120*5f757f3fSDimitry Andric if (!MaybeBuf) 121*5f757f3fSDimitry Andric return MaybeBuf.takeError(); 122*5f757f3fSDimitry Andric auto Serializer = std::move(*MaybeSerializer); 123*5f757f3fSDimitry Andric auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer()); 124*5f757f3fSDimitry Andric if (!MaybeParser) 125*5f757f3fSDimitry Andric return MaybeParser.takeError(); 126*5f757f3fSDimitry Andric auto &Parser = **MaybeParser; 127*5f757f3fSDimitry Andric 128*5f757f3fSDimitry Andric // Parse + reserialize all remarks. 129*5f757f3fSDimitry Andric auto MaybeRemark = Parser.next(); 130*5f757f3fSDimitry Andric for (; MaybeRemark; MaybeRemark = Parser.next()) 131*5f757f3fSDimitry Andric Serializer->emit(**MaybeRemark); 132*5f757f3fSDimitry Andric auto E = MaybeRemark.takeError(); 133*5f757f3fSDimitry Andric if (!E.isA<EndOfFileError>()) 134*5f757f3fSDimitry Andric return E; 135*5f757f3fSDimitry Andric consumeError(std::move(E)); 136*5f757f3fSDimitry Andric return Error::success(); 137*5f757f3fSDimitry Andric } 138*5f757f3fSDimitry Andric } // namespace bitstream2yaml 139*5f757f3fSDimitry Andric 140*5f757f3fSDimitry Andric static CommandRegistration Bitstream2YamlReg(&Bitstream2YAML, 141*5f757f3fSDimitry Andric bitstream2yaml::tryBitstream2YAML); 142*5f757f3fSDimitry Andric static CommandRegistration Yaml2Bitstream(&YAML2Bitstream, 143*5f757f3fSDimitry Andric yaml2bitstream::tryYAML2Bitstream); 144