Files
revng-revng/lib/AutoEnforcer/Step.cpp
T
2021-05-31 17:07:33 +02:00

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);
}