55 static std::unique_ptr<Statistics>
58 return std::make_unique<Statistics>(sourceFile);
80 if (it->second < sizeInBytes)
99 static std::unique_ptr<Context>
102 return std::make_unique<Context>();
112 : Transformation(
"IOBarrierElimination")
120 auto & rvsdg =
module.Rvsdg();
125 statistics->startMarkStatistics();
127 statistics->stopMarkStatistics();
129 statistics->startSweepStatistics();
131 statistics->stopSweepStatistics();
155 const auto phiNode = util::assertedCast<const rvsdg::PhiNode>(&node);
156 markRegion(*phiNode->subregion());
160 const auto lambdaNode = util::assertedCast<const rvsdg::LambdaNode>(&node);
161 markRegion(*lambdaNode->subregion());
165 const auto & addressOperand = *LoadOperation::AddressInput(node).origin();
166 const auto sizeInBytes = GetTypeStoreSize(*loadOperation.GetLoadedType());
168 auto [ioBarrierNode, ioBarrierOp] =
169 rvsdg::TryGetSimpleNodeAndOptionalOp<IOBarrierOperation>(addressOperand);
172 const auto & barredAddressOperand =
173 *IOBarrierOperation::BarredInput(*ioBarrierNode).origin();
174 if (const auto & ioStateInput = IOBarrierOperation::getIOStateInput(*ioBarrierNode);
175 rvsdg::TryGetRegionParentNode<rvsdg::LambdaNode>(*ioStateInput.origin()))
180 context_->markDereferenceable(barredAddressOperand, sizeInBytes);
187 context_->markDereferenceable(addressOperand, sizeInBytes);
195 for (
auto & node : region.
Nodes())
201 const auto phiNode = util::assertedCast<const rvsdg::PhiNode>(&node);
202 sweepRegion(*phiNode->subregion());
206 const auto lambdaNode = util::assertedCast<const rvsdg::LambdaNode>(&node);
207 sweepRegion(*lambdaNode->subregion());
211 auto & loadAddress = LoadOperation::AddressInput(node);
212 auto [ioBarrierNode, ioBarrierOp] =
213 rvsdg::TryGetSimpleNodeAndOptionalOp<IOBarrierOperation>(*loadAddress.origin());
217 auto & barredAddressOperand = *IOBarrierOperation::BarredInput(*ioBarrierNode).origin();
218 const auto sizeOpt = context_->isDereferenceable(barredAddressOperand);
219 const auto sizeInBytes = GetTypeStoreSize(*loadOperation.GetLoadedType());
220 if (!sizeOpt.has_value() || sizeOpt.value() < sizeInBytes)
223 loadAddress.divert_to(&barredAddressOperand);
static jlm::util::StatisticsCollector statisticsCollector
std::unordered_map< const rvsdg::Output *, size_t > dereferenceableOutputs_
std::optional< size_t > isDereferenceable(const rvsdg::Output &output) const
bool markDereferenceable(const rvsdg::Output &output, const size_t sizeInBytes)
static std::unique_ptr< Context > create()
~Statistics() override=default
Statistics(const util::FilePath &sourceFile)
void stopSweepStatistics() noexcept
void stopMarkStatistics() noexcept
const char * SweepTimerLabel_
static std::unique_ptr< Statistics > create(const util::FilePath &sourceFile)
void startSweepStatistics() noexcept
void startMarkStatistics() noexcept
const char * MarkTimerLabel_
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
void markNode(const rvsdg::Node &node)
void markRegion(rvsdg::Region ®ion)
~IOBarrierElimination() override
void sweepRegion(rvsdg::Region ®ion)
std::unique_ptr< Context > context_
virtual const Operation & GetOperation() const noexcept=0
Represent acyclic RVSDG subgraphs.
void prune(bool recursive)
NodeRange Nodes() noexcept
const std::optional< util::FilePath > & SourceFilePath() const noexcept
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
util::Timer & GetTimer(const std::string &name)
util::Timer & AddTimer(std::string name)
Global memory state passed between functions.
void MatchType(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.