12#ifndef LLVM_EXECUTIONENGINE_ORC_WAITINGONGRAPHOPREPLAY_H
13#define LLVM_EXECUTIONENGINE_ORC_WAITINGONGRAPHOPREPLAY_H
43template <
typename ContainerIdT,
typename ElementIdT>
57 recordSimplify(
const std::vector<std::unique_ptr<SuperNode>> &SNs)
override {
58 std::scoped_lock<std::mutex> Lock(M);
59 recordSuperNodes(
"simplify-and-emit", SNs);
64 std::scoped_lock<std::mutex> Lock(M);
66 recordContainerElementsMap(
" ",
"failed",
Failed);
71 std::scoped_lock<std::mutex> Lock(M);
79 ContainerIdMap.insert(std::make_pair(
C, ContainerIdMap.size())).first;
86 const ElementSet &Elements) {
87 assert(ContainerIdMap.count(
C));
88 auto &ElementIdMap = ContainerIdMap[
C].ElementIdMap;
89 for (
auto &
E : Elements) {
91 ElementIdMap.insert(std::make_pair(
E, ElementIdMap.size())).first;
92 OS <<
" " <<
I->second;
97 struct ContainerIdInfo {
98 ContainerIdInfo() =
default;
99 ContainerIdInfo(
size_t Id) : Id(Id) {}
106 const std::vector<std::unique_ptr<SuperNode>> &SNs) {
107 OS <<
OpName <<
" " << SNs.size() <<
"\n";
108 for (
size_t I = 0;
I != SNs.size(); ++
I) {
109 OS <<
" sn " <<
I <<
"\n";
110 recordContainerElementsMap(
" ",
"defs", SNs[
I]->defs());
111 recordContainerElementsMap(
" ",
"deps", SNs[
I]->deps());
115 void recordContainerElementsMap(StringRef Indent, StringRef MapName,
116 const ContainerElementsMap &M) {
117 OS << Indent << MapName <<
" " << M.size() <<
"\n";
118 for (
auto &[Container, Elements] : M) {
119 OS << Indent <<
" container ";
121 OS <<
" " <<
Elements.size() <<
"\n";
122 OS << Indent <<
" elements ";
132template <
typename ContainerIdT,
typename ElementIdT>
149 std::vector<std::unique_ptr<SuperNode>>
SNs;
162 using Op = std::variant<SimplifyAndEmitOp, FailOp>;
169 if (
auto *SimplifyAndEmit = std::get_if<SimplifyAndEmitOp>(&O))
171 else if (
auto *
Fail = std::get_if<FailOp>(&O))
177 auto ER =
G.emit(std::move(SR),
181 if (
I !=
Failed.end() &&
I->second.count(
E))
182 return ExternalState::Failed;
186 if (
I !=
Ready.end() &&
I->second.count(
E))
187 return ExternalState::Ready;
189 return ExternalState::None;
191 for (
auto &SN : ER.Ready)
192 for (
auto &[Container, Elems] : SN->defs())
193 Ready[Container].insert(Elems.begin(), Elems.end());
194 for (
auto &SN : ER.Failed)
195 for (
auto &[Container, Elems] : SN->defs())
196 Failed[Container].insert(Elems.begin(), Elems.end());
200 for (
auto &[Container, Elems] : NewlyFailed)
201 Failed[Container].insert(Elems.begin(), Elems.end());
203 auto FailedSNs =
G.fail(NewlyFailed);
204 for (
auto &SN : FailedSNs)
205 for (
auto &[Container, Elems] : SN->defs())
206 Failed[Container].insert(Elems.begin(), Elems.end());
247 : P(
std::
move(P)), Input(Input), PrevInput(Input) {}
258 Input = PrevInput =
Other.PrevInput;
270 auto PR = P->parseNext(Input);
272 return PR.takeError();
273 std::tie(CurOp, Input) = std::move(*PR);
283 assert(CurOp &&
"Dereferencing end/invalid iterator");
289 assert(CurOp &&
"Dereferencing end/invalid iterator");
303 std::shared_ptr<OpParser>
P;
305 std::optional<Op> CurOp;
312template <
typename ContainerIdT,
typename ElementIdT>
314 typename WaitingOnGraphOpReplay<ContainerIdT, ElementIdT>::OpIterator>>
319 class Parser :
public Replay::OpParser {
321 using ParseResult =
typename Replay::OpParser::ParseResult;
322 using SuperNode =
typename Replay::SuperNode;
323 using ContainerElementsMap =
typename Replay::ContainerElementsMap;
328 auto Line = getNextLine(
Input);
332 "unexpected end of input (missing 'end')",
335 if (Line.consume_front(
"simplify-and-emit ")) {
337 if (Line.trim().consumeInteger(10, NumSNs))
339 "expected supernode count after 'simplify-and-emit'",
341 auto SNs = parseSuperNodes(
Input, NumSNs);
343 return SNs.takeError();
344 return this->parsedSimplifyAndEmit(std::move(*SNs),
Input);
345 }
else if (Line.trim() ==
"fail") {
346 auto FailElems = parseContainerElementsMap(
"failed",
Input);
348 return FailElems.takeError();
349 return this->parsedFail(std::move(*FailElems),
Input);
350 }
else if (Line.trim() ==
"end")
351 return this->parsedEnd(
Input);
364 }
while (Line.empty() && !
Input.empty());
370 std::vector<std::unique_ptr<SuperNode>> SNs;
371 for (
size_t I = 0;
I != NumSNs; ++
I) {
374 if (!Line.consume_front(
"sn "))
378 auto Defs = parseContainerElementsMap(
"defs",
Input);
380 return Defs.takeError();
381 auto Deps = parseContainerElementsMap(
"deps",
Input);
383 return Deps.takeError();
386 std::make_unique<SuperNode>(std::move(*Defs), std::move(*Deps)));
388 return std::move(SNs);
394 auto Line = getNextLine(
Input);
395 if (!Line.consume_front(ArgName))
398 size_t NumContainers;
399 if (Line.trim().consumeInteger(10, NumContainers))
403 ContainerElementsMap M;
404 for (
size_t I = 0;
I != NumContainers; ++
I) {
405 Line = getNextLine(
Input);
406 if (!Line.consume_front(
"container "))
412 if (Line.consumeInteger(10, Container))
416 if (M.count(Container))
418 "expected container id to be unique within " + ArgName,
422 if (Line.trim().consumeInteger(10, NumElements))
425 if (NumElements == 0)
427 Twine(Container) +
" must be > 0",
430 Line = getNextLine(
Input);
431 if (!Line.consume_front(
"elements "))
435 auto &Elements = M[Container];
436 for (
size_t J = 0; J != NumElements; ++J) {
439 if (Line.consumeInteger(10, Elem))
442 if (Elements.count(Elem))
444 "expected element id to be unique within container " +
447 Elements.insert(Elem);
456 typename Replay::OpIterator Begin(std::make_shared<Parser>(), InputBuffer);
457 typename Replay::OpIterator End;
458 if ((Err = Begin.inc()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
This class represents success/failure for parsing-like operations that find it important to chain tog...
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A wrapper class for fallible iterators.
A range adaptor for a pair of iterators.
OpIterator & operator=(OpIterator &&)=default
Error inc()
Move to next record.
friend bool operator!=(const OpIterator &LHS, const OpIterator &RHS)
const Op & operator*() const
friend bool operator==(const OpIterator &LHS, const OpIterator &RHS)
Compare iterators. End iterators compare equal.
OpIterator(OpIterator &&)=default
OpIterator & operator=(const OpIterator &Other)
OpIterator(std::shared_ptr< OpParser > P, StringRef Input)
Construct a fallible iterator reading from the given input buffer using the given parser.
OpIterator()=default
Default constructed fallible iterator. Serves as end value.
OpIterator(const OpIterator &Other)
Expected< ParseResult > parsedEnd(StringRef Input)
virtual ~OpParser()=default
Expected< ParseResult > parsedSimplifyAndEmit(std::vector< std::unique_ptr< SuperNode > > SNs, StringRef Input)
std::pair< std::optional< Op >, StringRef > ParseResult
Expected< ParseResult > parsedFail(ContainerElementsMap NewlyFailed, StringRef Input)
virtual Expected< ParseResult > parseNext(StringRef Input)=0
typename Graph::ContainerElementsMap ContainerElementsMap
typename Graph::ContainerId ContainerId
typename Graph::SuperNode SuperNode
std::variant< SimplifyAndEmitOp, FailOp > Op
A parsed operation – either a simplify-and-emit or a fail.
WaitingOnGraph< ContainerIdT, ElementIdT > Graph
typename Graph::ExternalState ExternalState
typename Graph::ElementId ElementId
virtual void printContainer(const ContainerId &C)
WaitingOnGraphOpStreamRecorder(raw_ostream &OS)
void recordFail(const ContainerElementsMap &Failed) override
void recordSimplify(const std::vector< std::unique_ptr< SuperNode > > &SNs) override
void recordEnd() override
virtual void printElementsIn(const ContainerId &C, const ElementSet &Elements)
WaitingOnGraph class template.
static SimplifyResult simplify(std::vector< std::unique_ptr< SuperNode > > SNs, OpRecorder *Rec=nullptr)
Preprocess a list of SuperNodes to remove all intra-SN dependencies.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
iterator_range< fallible_iterator< typename WaitingOnGraphOpReplay< ContainerIdT, ElementIdT >::OpIterator > > readWaitingOnGraphOpsFromBuffer(StringRef InputBuffer, Error &Err)
Returns a fallible iterator range over the operations in the given buffer.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
testing::Matcher< const detail::ErrorHolder & > Failed()
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
iterator_range< fallible_iterator< Underlying > > make_fallible_range(Underlying I, Underlying E, Error &Err)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
A fail operation parsed from the input.
FailOp(ContainerElementsMap Failed)
ContainerElementsMap Failed
FailOp(FailOp &&)=default
FailOp & operator=(FailOp &&)=default
ContainerElementsMap Failed
ContainerElementsMap Ready
void replayFail(ContainerElementsMap NewlyFailed)
void replaySimplifyAndEmit(std::vector< std::unique_ptr< SuperNode > > SNs)
A simplify-and-emit operation parsed from the input.
SimplifyAndEmitOp & operator=(SimplifyAndEmitOp &&)=default
SimplifyAndEmitOp(SimplifyAndEmitOp &&)=default
SimplifyAndEmitOp()=default
SimplifyAndEmitOp(std::vector< std::unique_ptr< SuperNode > > SNs)
std::vector< std::unique_ptr< SuperNode > > SNs