cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
170 lines
6.5 KiB
C++
170 lines
6.5 KiB
C++
//===---------- MachinePassManager.cpp ------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the pass management machinery for machine functions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/MachinePassManager.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/PassManagerImpl.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
|
|
using namespace llvm;
|
|
|
|
AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key;
|
|
|
|
namespace llvm {
|
|
template class LLVM_EXPORT_TEMPLATE AnalysisManager<MachineFunction>;
|
|
template class PassManager<MachineFunction>;
|
|
template class LLVM_EXPORT_TEMPLATE
|
|
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
|
|
template class LLVM_EXPORT_TEMPLATE
|
|
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Function>;
|
|
template class LLVM_EXPORT_TEMPLATE
|
|
OuterAnalysisManagerProxy<ModuleAnalysisManager, MachineFunction>;
|
|
} // namespace llvm
|
|
|
|
bool FunctionAnalysisManagerMachineFunctionProxy::Result::invalidate(
|
|
MachineFunction &IR, const PreservedAnalyses &PA,
|
|
MachineFunctionAnalysisManager::Invalidator &Inv) {
|
|
// MachineFunction passes should not invalidate Function analyses.
|
|
// TODO: verify that PA doesn't invalidate Function analyses.
|
|
return false;
|
|
}
|
|
|
|
template <>
|
|
bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
|
|
Module &M, const PreservedAnalyses &PA,
|
|
ModuleAnalysisManager::Invalidator &Inv) {
|
|
// If literally everything is preserved, we're done.
|
|
if (PA.areAllPreserved())
|
|
return false; // This is still a valid proxy.
|
|
|
|
// If this proxy isn't marked as preserved, then even if the result remains
|
|
// valid, the key itself may no longer be valid, so we clear everything.
|
|
//
|
|
// Note that in order to preserve this proxy, a module pass must ensure that
|
|
// the MFAM has been completely updated to handle the deletion of functions.
|
|
// Specifically, any MFAM-cached results for those functions need to have been
|
|
// forcibly cleared. When preserved, this proxy will only invalidate results
|
|
// cached on functions *still in the module* at the end of the module pass.
|
|
auto PAC = PA.getChecker<MachineFunctionAnalysisManagerModuleProxy>();
|
|
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
|
|
InnerAM->clear();
|
|
return true;
|
|
}
|
|
|
|
// FIXME: be more precise, see
|
|
// FunctionAnalysisManagerModuleProxy::Result::invalidate.
|
|
if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
|
|
InnerAM->clear();
|
|
return true;
|
|
}
|
|
|
|
// Return false to indicate that this result is still a valid proxy.
|
|
return false;
|
|
}
|
|
|
|
template <>
|
|
bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
|
|
Function &F, const PreservedAnalyses &PA,
|
|
FunctionAnalysisManager::Invalidator &Inv) {
|
|
// If literally everything is preserved, we're done.
|
|
if (PA.areAllPreserved())
|
|
return false; // This is still a valid proxy.
|
|
|
|
// If this proxy isn't marked as preserved, then even if the result remains
|
|
// valid, the key itself may no longer be valid, so we clear everything.
|
|
//
|
|
// Note that in order to preserve this proxy, a module pass must ensure that
|
|
// the MFAM has been completely updated to handle the deletion of functions.
|
|
// Specifically, any MFAM-cached results for those functions need to have been
|
|
// forcibly cleared. When preserved, this proxy will only invalidate results
|
|
// cached on functions *still in the module* at the end of the module pass.
|
|
auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>();
|
|
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) {
|
|
InnerAM->clear();
|
|
return true;
|
|
}
|
|
|
|
// FIXME: be more precise, see
|
|
// FunctionAnalysisManagerModuleProxy::Result::invalidate.
|
|
if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
|
|
InnerAM->clear();
|
|
return true;
|
|
}
|
|
|
|
// Return false to indicate that this result is still a valid proxy.
|
|
return false;
|
|
}
|
|
|
|
PreservedAnalyses
|
|
FunctionToMachineFunctionPassAdaptor::run(Function &F,
|
|
FunctionAnalysisManager &FAM) {
|
|
MachineFunctionAnalysisManager &MFAM =
|
|
FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(F)
|
|
.getManager();
|
|
PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
|
|
PreservedAnalyses PA = PreservedAnalyses::all();
|
|
// Do not codegen any 'available_externally' functions at all, they have
|
|
// definitions outside the translation unit.
|
|
if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
|
|
return PreservedAnalyses::all();
|
|
|
|
MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF();
|
|
|
|
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
|
|
return PreservedAnalyses::all();
|
|
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
|
|
MFAM.invalidate(MF, PassPA);
|
|
PI.runAfterPass(*Pass, MF, PassPA);
|
|
PA.intersect(std::move(PassPA));
|
|
|
|
return PA;
|
|
}
|
|
|
|
void FunctionToMachineFunctionPassAdaptor::printPipeline(
|
|
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
|
|
OS << "machine-function(";
|
|
Pass->printPipeline(OS, MapClassName2PassName);
|
|
OS << ')';
|
|
}
|
|
|
|
template <>
|
|
PreservedAnalyses
|
|
PassManager<MachineFunction>::run(MachineFunction &MF,
|
|
AnalysisManager<MachineFunction> &MFAM) {
|
|
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
|
|
PreservedAnalyses PA = PreservedAnalyses::all();
|
|
for (auto &Pass : Passes) {
|
|
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
|
|
continue;
|
|
|
|
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
|
|
MFAM.invalidate(MF, PassPA);
|
|
PI.runAfterPass(*Pass, MF, PassPA);
|
|
PA.intersect(std::move(PassPA));
|
|
}
|
|
PA.preserveSet<AllAnalysesOn<MachineFunction>>();
|
|
return PA;
|
|
}
|
|
|
|
PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() {
|
|
PreservedAnalyses PA;
|
|
// Machine function passes are not allowed to modify the LLVM
|
|
// representation, therefore we should preserve all IR analyses.
|
|
PA.template preserveSet<AllAnalysesOn<Module>>();
|
|
PA.template preserveSet<AllAnalysesOn<Function>>();
|
|
return PA;
|
|
}
|