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...
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.