78 node->output(0)->divert_users(
bufOut);
134 auto res =
out->results.begin().ptr();
176 auto arg =
in->arguments.begin().ptr();
177 auto user = &arg->SingleUser();
207 auto loop =
dynamic_cast<LoopNode *
>(node);
261 std::vector<jlm::rvsdg::SimpleNode *>
nodes;
266 auto loop =
dynamic_cast<LoopNode *
>(node);
285 for (
auto node :
nodes)
290 if (
dl->capacity < capacity)
295 *node->input(0)->origin(),
296 *node->input(1)->origin(),
304static std::vector<size_t>
317 if (
op->IsPassThrough())
351static std::vector<size_t>
395 std::unordered_set<rvsdg::Input *> & frontier,
397 std::unordered_set<rvsdg::SimpleNode *> &
top_muxes)
404 auto user = &arg->SingleUser();
414 frontier.insert(&
out->SingleUser());
418 frontier.insert(&arg->SingleUser());
423 auto out =
tn.output(0);
425 frontier.insert(&
out->SingleUser());
451 frontier.insert(&arg->SingleUser());
465 std::unordered_set<rvsdg::Input *> & frontier,
467 std::unordered_set<rvsdg::SimpleNode *> &
top_muxes)
473 for (
auto in : frontier)
481 if (
f == frontier.end())
526 frontier.insert(&
out->SingleUser());
535 auto out =
be->argument();
540 frontier.insert(&
out->SingleUser());
548 auto out =
rr->output();
563 if (
f == frontier.end())
580 frontier.insert(&
inner_loop->output(
i)->SingleUser());
588 if (!frontier.empty())
590 std::unordered_map<rvsdg::Output *, std::string>
o_color;
591 std::unordered_map<rvsdg::Input *, std::string>
i_color;
592 for (
auto i : frontier)
614 std::unordered_set<rvsdg::Input *> frontier;
616 std::unordered_set<rvsdg::SimpleNode *>
top_muxes;
618 std::unordered_set<rvsdg::Input *>
frontier2(frontier);
619 std::cout <<
"CalculateLoopCycleDepth(" << loop <<
", " <<
analyze_inner_loop <<
")" << std::endl;
628 std::unordered_map<rvsdg::Output *, std::string>
o_color;
629 std::unordered_map<rvsdg::Input *, std::string>
i_color;
630 std::unordered_map<rvsdg::Output *, std::string>
tail_label;
642 std::cout <<
"second iteration" << std::endl;
677 if (arg && arg->input())
703 node->output(0)->divert_users(
bufOut);
737 std::unordered_set<rvsdg::Input *> frontier;
739 std::unordered_set<rvsdg::SimpleNode *>
top_muxes;
744 auto out =
tn.output(0);
758 std::unordered_map<rvsdg::Output *, std::string>
o_color;
759 std::unordered_map<rvsdg::Input *, std::string>
i_color;
760 std::unordered_map<rvsdg::Output *, std::string>
tail_label;
763 for (
auto i : frontier)
777 for (
auto in : frontier)
785 if (
f == frontier.end())
835 frontier.insert(&
out->SingleUser());
844 auto out =
be->argument();
848 frontier.insert(&
out->SingleUser());
856 auto out =
rr->output();
871 if (
f == frontier.end())
891 auto user = &
inner_loop->input(
i)->arguments.begin().ptr()->SingleUser();
911 frontier.insert(&
inner_loop->output(
i)->SingleUser());
941 if (
auto loop =
dynamic_cast<LoopNode *
>(node))
963 const auto rootRegion = &graph.GetRootRegion();
966 throw std::logic_error(
"Root should have only one node now");
972 throw std::logic_error(
"Node needs to be a lambda");
std::vector< rvsdg::Node * > nodes
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
~BufferInsertion() noexcept override
static std::vector< jlm::rvsdg::Output * > create(jlm::rvsdg::Output &value, size_t capacity, bool pass_through=false)
static std::vector< jlm::rvsdg::Output * > create(jlm::rvsdg::Output &addr, jlm::rvsdg::Output &load_result, size_t capacity)
rvsdg::Region * subregion() const noexcept
bool IsDead() const noexcept
Determines whether the node is dead.
size_t ninputs() const noexcept
size_t noutputs() const noexcept
rvsdg::Input & SingleUser() noexcept
Represents the argument of a region.
Represents the result of a region.
Represent acyclic RVSDG subgraphs.
RegionArgumentRange Arguments() noexcept
TopNodeRange TopNodes() noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
Iterator begin() noexcept
#define JLM_UNREACHABLE(msg)
static rvsdg::Input * FindUserNode(rvsdg::Output *out)
static size_t MemoryLatency
static void CalculateLoopCycleDepth(LoopNode *loop, std::unordered_map< rvsdg::Output *, size_t > &output_cycles, bool analyze_inner_loop=false)
static void CreateLoopFrontier(const LoopNode *loop, std::unordered_map< rvsdg::Output *, size_t > &output_cycles, std::unordered_set< rvsdg::Input * > &frontier, std::unordered_set< BackEdgeResult * > &stream_backedges, std::unordered_set< rvsdg::SimpleNode * > &top_muxes)
static void PushCycleFrontier(std::unordered_map< rvsdg::Output *, size_t > &output_cycles, std::unordered_set< rvsdg::Input * > &frontier, std::unordered_set< BackEdgeResult * > &stream_backedges, std::unordered_set< rvsdg::SimpleNode * > &top_muxes)
static void AddBuffers(rvsdg::Region *region)
static constexpr uint32_t round_up_pow2(uint32_t x)
static std::vector< size_t > NodeCycles(rvsdg::SimpleNode *node, std::vector< size_t > &input_cycles)
static void divert_users(jlm::rvsdg::Output *output, Context &ctx)
static bool is_constant(const rvsdg::Node *node)
static void OptimizeBuffer(rvsdg::SimpleNode *node)
static std::vector< size_t > NodeCapacity(rvsdg::SimpleNode *node, std::vector< size_t > &input_capacities)
static void PlaceBuffer(rvsdg::Output *out, size_t capacity, bool passThrough)
const size_t UnlimitedBufferCapacity
static void CalculateLoopDepths(rvsdg::Region *region)
static size_t PlaceBufferLoop(rvsdg::Output *out, size_t min_capacity, bool passThrough)
static void OptimizeLoop(LoopNode *loopNode)
static void OptimizeAddrQ(rvsdg::SimpleNode *node)
void setMemoryLatency(size_t memoryLatency)
static void MaximizeBuffers(rvsdg::Region *region)
static void AdjustLoopBuffers(LoopNode *loop, std::unordered_map< rvsdg::Output *, size_t > &output_cycles, std::unordered_map< rvsdg::Output *, size_t > &buffer_capacity, bool analyze_inner_loop=false)
const size_t MaximumBufferSize
static void remove(Node *node)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.