mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
90 lines
2.8 KiB
C++
90 lines
2.8 KiB
C++
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng/AutoEnforcer/Step.h"
|
|
#include "revng/Support/Debug.h"
|
|
|
|
using namespace llvm;
|
|
using namespace std;
|
|
using namespace AutoEnforcer;
|
|
|
|
EnforcerWrapper &EnforcerWrapper::operator=(const EnforcerWrapper &Other) {
|
|
if (this == &Other)
|
|
return *this;
|
|
|
|
Enf = Other.Enf->clone();
|
|
return *this;
|
|
}
|
|
|
|
BackingContainersStatus
|
|
Step::satisfiableGoals(const BackingContainersStatus &RequiredGoals,
|
|
BackingContainersStatus &ToLoad) const {
|
|
|
|
BackingContainersStatus Targets = RequiredGoals;
|
|
for (const auto &Enforcer :
|
|
llvm::make_range(Enforcers.rbegin(), Enforcers.rend())) {
|
|
Targets = Enforcer.getRequirements(Targets);
|
|
removeSatisfiedGoals(Targets, ToLoad);
|
|
}
|
|
|
|
return Targets;
|
|
}
|
|
|
|
BackingContainers Step::cloneAndRun(const BackingContainersStatus &Targets) {
|
|
auto RunningContainers = BackingContainer.cloneFiltered(Targets);
|
|
for (auto &Enforcer : Enforcers)
|
|
Enforcer.run(RunningContainers);
|
|
return RunningContainers;
|
|
}
|
|
|
|
using TargetContainer = BackingContainersStatus::TargetContainer;
|
|
|
|
void Step::removeSatisfiedGoals(TargetContainer &RequiredInputs,
|
|
const BackingContainerBase &CachedSymbols,
|
|
TargetContainer &ToLoad) {
|
|
|
|
const auto IsCached =
|
|
[&ToLoad, &CachedSymbols](const AutoEnforcerTarget &Target) -> bool {
|
|
bool MustBeLoaded = CachedSymbols.contains(Target);
|
|
if (MustBeLoaded)
|
|
ToLoad.emplace_back(Target);
|
|
return MustBeLoaded;
|
|
};
|
|
|
|
llvm::erase_if(RequiredInputs, IsCached);
|
|
}
|
|
|
|
void Step::removeSatisfiedGoals(BackingContainersStatus &Targets,
|
|
BackingContainersStatus &ToLoad) const {
|
|
for (auto &RequiredInputsFromContainer : Targets) {
|
|
llvm::StringRef ContainerName = RequiredInputsFromContainer.first();
|
|
auto &RequiredInputs = RequiredInputsFromContainer.second;
|
|
auto &ToLoadFromCurrentContainer = ToLoad[ContainerName];
|
|
removeSatisfiedGoals(RequiredInputs,
|
|
BackingContainer.get(ContainerName),
|
|
ToLoadFromCurrentContainer);
|
|
}
|
|
}
|
|
|
|
BackingContainersStatus
|
|
Step::deduceResults(BackingContainersStatus Input) const {
|
|
for (const auto &Enforcer : Enforcers)
|
|
Input = Enforcer.deduceResults(Input);
|
|
return Input;
|
|
}
|
|
|
|
void BackingContainersStatus::merge(const BackingContainersStatus &Other) {
|
|
for (const auto &Container : Other.ContainersStatus) {
|
|
const auto &BackingContainerName = Container.first();
|
|
const auto &BackingContainerSymbols = Container.second;
|
|
auto &ToMergeIn = ContainersStatus[BackingContainerName];
|
|
|
|
copy(BackingContainerSymbols, back_inserter(ToMergeIn));
|
|
}
|
|
}
|
|
|
|
Error Step::invalidate(const BackingContainersStatus &ToRemove) {
|
|
return getBackingContainers().remove(ToRemove);
|
|
}
|