Merge pull request #150 from ddunbar/optimize-rule-dep-search
Optimize the rule dependency search query.
diff --git a/lib/BuildSystem/BuildSystemFrontend.cpp b/lib/BuildSystem/BuildSystemFrontend.cpp
index 4799d7c..45ecff1 100644
--- a/lib/BuildSystem/BuildSystemFrontend.cpp
+++ b/lib/BuildSystem/BuildSystemFrontend.cpp
@@ -232,6 +232,15 @@
};
struct BuildSystemFrontendDelegateImpl {
+
+ /// The status of delegate.
+ enum class Status {
+ Uninitialized = 0,
+ Initialized,
+ InitializationFailure,
+ Cancelled,
+ };
+
llvm::SourceMgr& sourceMgr;
const BuildSystemInvocation& invocation;
@@ -248,6 +257,28 @@
const BuildSystemInvocation& invocation)
: sourceMgr(sourceMgr), invocation(invocation),
executionQueueDelegate(*this) {}
+
+private:
+ /// The status of the delegate.
+ std::atomic<Status> status{Status::Uninitialized};
+
+public:
+
+ /// Set the status of delegate to the given value.
+ ///
+ /// It is not possible to update the status once status is set to initialization failure.
+ void setStatus(Status newStatus) {
+ // Disallow changing status if there was an initialization failure.
+ if (status == Status::InitializationFailure) {
+ return;
+ }
+ status = newStatus;
+ }
+
+ /// Returns the current status.
+ Status getStatus() {
+ return status;
+ }
};
bool BuildSystemFrontendExecutionQueueDelegate::showVerboseOutput() const {
@@ -378,6 +409,11 @@
void BuildSystemFrontendDelegate::cancel() {
auto delegateImpl = static_cast<BuildSystemFrontendDelegateImpl*>(impl);
+ assert(delegateImpl->getStatus() != BuildSystemFrontendDelegateImpl::Status::Uninitialized);
+
+ // Update the status to cancelled.
+ delegateImpl->setStatus(BuildSystemFrontendDelegateImpl::Status::Cancelled);
+
auto system = delegateImpl->system;
if (system) {
system->cancel();
@@ -388,6 +424,12 @@
auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);
impl->numFailedCommands = 0;
+ impl->numErrors = 0;
+
+ // Update status back to initialized on reset.
+ if (impl->getStatus() == BuildSystemFrontendDelegateImpl::Status::Cancelled) {
+ impl->setStatus(BuildSystemFrontendDelegateImpl::Status::Initialized);
+ }
}
void BuildSystemFrontendDelegate::hadCommandFailure() {
@@ -540,9 +582,28 @@
}
bool BuildSystemFrontend::build(StringRef targetToBuild) {
+
+ auto delegateImpl =
+ static_cast<BuildSystemFrontendDelegateImpl*>(delegate.impl);
+
+ // We expect build to be called in these states only.
+ assert(delegateImpl->getStatus() == BuildSystemFrontendDelegateImpl::Status::Uninitialized
+ || delegateImpl->getStatus() == BuildSystemFrontendDelegateImpl::Status::Initialized);
+
+ // Set the delegate status to initialized.
+ delegateImpl->setStatus(BuildSystemFrontendDelegateImpl::Status::Initialized);
+
// Initialize the build system, if necessary
if (!buildSystem.hasValue()) {
- if (!initialize())
+ if (!initialize()) {
+ // Set status to initialization failure. It is not possible to recover from this state.
+ delegateImpl->setStatus(BuildSystemFrontendDelegateImpl::Status::InitializationFailure);
+ return false;
+ }
+ }
+
+ // If delegate was told to cancel while we were initializing, abort now.
+ if (delegateImpl->getStatus() == BuildSystemFrontendDelegateImpl::Status::Cancelled) {
return false;
}