14#include "llvm/ADT/STLExtras.h"
15#include "llvm/Support/Error.h"
16#include "llvm/Support/ErrorHandling.h"
24 : LU(
std::move(LU)) {}
29 enum class State { Unvisited, Visiting, Visited };
31 std::map<AnalysisName, State> Marks;
32 std::vector<AnalysisName> Path;
33 std::vector<std::unique_ptr<AnalysisBase>>
Result;
35 explicit Visitor(
size_t N) {
40 std::string formatCycle(
const AnalysisName &CycleEntry)
const {
41 auto CycleBegin = llvm::find(Path, CycleEntry);
43 llvm::raw_string_ostream OS(Cycle);
44 llvm::interleave(llvm::make_range(CycleBegin, Path.end()), OS,
" -> ");
45 OS <<
" -> " << CycleEntry;
49 llvm::Error visit(
const AnalysisName &Name) {
50 auto [It, _] = Marks.emplace(Name, State::Unvisited);
54 return llvm::Error::success();
58 "cycle detected: {0}", formatCycle(Name))
61 case State::Unvisited: {
62 It->second = State::Visiting;
65 llvm::Expected<std::unique_ptr<AnalysisBase>>
V =
66 AnalysisRegistry::instantiate(Name);
73 std::unique_ptr<AnalysisBase> Analysis = std::move(*
V);
75 for (
const auto &Dep : Analysis->getDependencyNames()) {
76 if (
auto Err = visit(Dep)) {
83 It->second = State::Visited;
85 Result.push_back(std::move(Analysis));
87 return llvm::Error::success();
90 llvm_unreachable(
"unhandled State");
94 Visitor
V(Roots.size());
95 for (
const auto &Root : Roots) {
96 if (
auto Err =
V.visit(Root)) {
97 return std::move(Err);
100 return std::move(
V.Result);
105 if (
auto Err = Summary.initialize())
109 if (DataIt != LU->Data.end()) {
110 for (
auto &[Id, EntitySummary] : DataIt->second)
111 if (
auto Err = Summary.add(Id, *EntitySummary))
114 return Summary.finalize();
119 std::map<AnalysisName, const AnalysisResult *> DepMap;
122 auto It = Suite.Data.find(DepName);
123 if (It == Suite.Data.end()) {
125 "dependency graph is not topologically sorted",
128 DepMap[DepName] = It->second.get();
131 if (
auto Err = Derived.initialize(DepMap)) {
136 auto StepOrErr = Derived.step();
138 return StepOrErr.takeError();
145 if (
auto Err = Derived.finalize()) {
149 return llvm::Error::success();
152llvm::Expected<WPASuite> AnalysisDriver::execute(
154 llvm::ArrayRef<std::unique_ptr<AnalysisBase>> Sorted)
const {
156 Suite.IdTable = std::move(IdTable);
158 for (
auto &Analysis : Sorted) {
159 switch (Analysis->TheKind) {
160 case AnalysisBase::Kind::Summary: {
161 SummaryAnalysisBase &SA =
static_cast<SummaryAnalysisBase &
>(*Analysis);
162 if (
auto Err = executeSummaryAnalysis(SA, Suite)) {
163 return std::move(Err);
167 case AnalysisBase::Kind::Derived: {
168 DerivedAnalysisBase &DA =
static_cast<DerivedAnalysisBase &
>(*Analysis);
169 if (
auto Err = executeDerivedAnalysis(DA, Suite)) {
170 return std::move(Err);
175 AnalysisName Name = Analysis->getAnalysisName();
176 Suite.Data.emplace(std::move(Name), std::move(*Analysis).takeResult());
179 return std::move(Suite);
183 auto ExpectedSorted = toposort(AnalysisRegistry::names());
184 if (!ExpectedSorted) {
185 return ExpectedSorted.takeError();
187 return execute(std::move(LU->IdTable), *ExpectedSorted);
192 auto ExpectedSorted = toposort(Names);
193 if (!ExpectedSorted) {
194 return ExpectedSorted.takeError();
197 return execute(LU->IdTable, *ExpectedSorted);
Result
Implement __builtin_bit_cast and related operations.
virtual const std::vector< AnalysisName > & getDependencyNames() const =0
AnalysisNames of all AnalysisResult dependencies.
virtual AnalysisName getAnalysisName() const =0
Name of this analysis.
llvm::Expected< WPASuite > run() const
Type-safe variant of run(names).
AnalysisDriver(std::unique_ptr< LUSummary > LU)
Uniquely identifies a whole-program analysis and the AnalysisResult it produces.
Type-erased base for derived analyses.
Manages entity name interning and provides efficient EntityId handles.
static ErrorBuilder create(std::error_code EC, const char *Fmt, Args &&...ArgVals)
Create an ErrorBuilder with an error code and formatted message.
static void fatal(const char *Fmt, Args &&...ArgVals)
Report a fatal error with formatted message and terminate execution.
llvm::Error build() const
Build and return the final error.
Type-erased base for summary analyses.
virtual SummaryName getSummaryName() const =0
SummaryName of the EntitySummary type this analysis consumes.
Bundles the EntityIdTable (moved from the LUSummary) and the analysis results produced by one Analysi...
Top level wrappers for InstallAPI frontend operations.
@ Result
The result type of a method or function.