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).
235 lines
7.5 KiB
C++
235 lines
7.5 KiB
C++
//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/InitializePasses.h"
|
|
#include "llvm/Target/TargetLoweringObjectFile.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include <cassert>
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::dwarf;
|
|
|
|
// Out of line virtual method.
|
|
MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
|
|
|
|
void MachineModuleInfo::initialize() {
|
|
ObjFileMMI = nullptr;
|
|
NextFnNum = 0;
|
|
}
|
|
|
|
void MachineModuleInfo::finalize() {
|
|
Context.reset();
|
|
// We don't clear the ExternalContext.
|
|
|
|
delete ObjFileMMI;
|
|
ObjFileMMI = nullptr;
|
|
}
|
|
|
|
MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
|
|
: TM(std::move(MMI.TM)),
|
|
Context(TM.getTargetTriple(), TM.getMCAsmInfo(), TM.getMCRegisterInfo(),
|
|
TM.getMCSubtargetInfo(), nullptr, &TM.Options.MCOptions, false),
|
|
MachineFunctions(std::move(MMI.MachineFunctions)) {
|
|
Context.setObjectFileInfo(TM.getObjFileLowering());
|
|
ObjFileMMI = MMI.ObjFileMMI;
|
|
ExternalContext = MMI.ExternalContext;
|
|
TheModule = MMI.TheModule;
|
|
}
|
|
|
|
MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
|
|
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
|
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
|
nullptr, &TM->Options.MCOptions, false) {
|
|
Context.setObjectFileInfo(TM->getObjFileLowering());
|
|
initialize();
|
|
}
|
|
|
|
MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM,
|
|
MCContext *ExtContext)
|
|
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
|
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
|
nullptr, &TM->Options.MCOptions, false),
|
|
ExternalContext(ExtContext) {
|
|
Context.setObjectFileInfo(TM->getObjFileLowering());
|
|
initialize();
|
|
}
|
|
|
|
MachineModuleInfo::~MachineModuleInfo() { finalize(); }
|
|
|
|
MachineFunction *
|
|
MachineModuleInfo::getMachineFunction(const Function &F) const {
|
|
auto I = MachineFunctions.find(&F);
|
|
return I != MachineFunctions.end() ? I->second.get() : nullptr;
|
|
}
|
|
|
|
MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) {
|
|
// Shortcut for the common case where a sequence of MachineFunctionPasses
|
|
// all query for the same Function.
|
|
if (LastRequest == &F)
|
|
return *LastResult;
|
|
|
|
auto I = MachineFunctions.insert(
|
|
std::make_pair(&F, std::unique_ptr<MachineFunction>()));
|
|
MachineFunction *MF;
|
|
if (I.second) {
|
|
// No pre-existing machine function, create a new one.
|
|
const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F);
|
|
MF = new MachineFunction(F, TM, STI, getContext(), NextFnNum++);
|
|
MF->initTargetMachineFunctionInfo(STI);
|
|
|
|
// MRI callback for target specific initializations.
|
|
TM.registerMachineRegisterInfoCallback(*MF);
|
|
|
|
// Update the set entry.
|
|
I.first->second.reset(MF);
|
|
} else {
|
|
MF = I.first->second.get();
|
|
}
|
|
|
|
LastRequest = &F;
|
|
LastResult = MF;
|
|
return *MF;
|
|
}
|
|
|
|
void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
|
|
MachineFunctions.erase(&F);
|
|
LastRequest = nullptr;
|
|
LastResult = nullptr;
|
|
}
|
|
|
|
void MachineModuleInfo::insertFunction(const Function &F,
|
|
std::unique_ptr<MachineFunction> &&MF) {
|
|
auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF)));
|
|
assert(I.second && "machine function already mapped");
|
|
(void)I;
|
|
}
|
|
|
|
namespace {
|
|
|
|
/// This pass frees the MachineFunction object associated with a Function.
|
|
class FreeMachineFunction : public FunctionPass {
|
|
public:
|
|
static char ID;
|
|
|
|
FreeMachineFunction() : FunctionPass(ID) {}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.addRequired<MachineModuleInfoWrapperPass>();
|
|
AU.addPreserved<MachineModuleInfoWrapperPass>();
|
|
}
|
|
|
|
bool runOnFunction(Function &F) override {
|
|
MachineModuleInfo &MMI =
|
|
getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
|
|
MMI.deleteMachineFunctionFor(F);
|
|
return true;
|
|
}
|
|
|
|
StringRef getPassName() const override {
|
|
return "Free MachineFunction";
|
|
}
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
char FreeMachineFunction::ID;
|
|
|
|
FunctionPass *llvm::createFreeMachineFunctionPass() {
|
|
return new FreeMachineFunction();
|
|
}
|
|
|
|
MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
|
|
const TargetMachine *TM)
|
|
: ImmutablePass(ID), MMI(TM) {
|
|
initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
|
|
const TargetMachine *TM, MCContext *ExtContext)
|
|
: ImmutablePass(ID), MMI(TM, ExtContext) {
|
|
initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
// Handle the Pass registration stuff necessary to use DataLayout's.
|
|
INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
|
|
"Machine Module Information", false, false)
|
|
char MachineModuleInfoWrapperPass::ID = 0;
|
|
|
|
static uint64_t getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
|
|
std::vector<const MDNode *> &LocInfos) {
|
|
// Look up a LocInfo for the buffer this diagnostic is coming from.
|
|
unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
|
|
const MDNode *LocInfo = nullptr;
|
|
if (BufNum > 0 && BufNum <= LocInfos.size())
|
|
LocInfo = LocInfos[BufNum - 1];
|
|
|
|
// If the inline asm had metadata associated with it, pull out a location
|
|
// cookie corresponding to which line the error occurred on.
|
|
uint64_t LocCookie = 0;
|
|
if (LocInfo) {
|
|
unsigned ErrorLine = SMD.getLineNo() - 1;
|
|
if (ErrorLine >= LocInfo->getNumOperands())
|
|
ErrorLine = 0;
|
|
|
|
if (LocInfo->getNumOperands() != 0)
|
|
if (const ConstantInt *CI =
|
|
mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
|
|
LocCookie = CI->getZExtValue();
|
|
}
|
|
|
|
return LocCookie;
|
|
}
|
|
|
|
bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
|
|
MMI.initialize();
|
|
MMI.TheModule = &M;
|
|
LLVMContext &Ctx = M.getContext();
|
|
MMI.getContext().setDiagnosticHandler(
|
|
[&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
|
|
const SourceMgr &SrcMgr,
|
|
std::vector<const MDNode *> &LocInfos) {
|
|
uint64_t LocCookie = 0;
|
|
if (IsInlineAsm)
|
|
LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
|
|
Ctx.diagnose(
|
|
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
|
|
});
|
|
return false;
|
|
}
|
|
|
|
bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
|
|
MMI.finalize();
|
|
return false;
|
|
}
|
|
|
|
AnalysisKey MachineModuleAnalysis::Key;
|
|
|
|
MachineModuleAnalysis::Result
|
|
MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
|
|
MMI.TheModule = &M;
|
|
LLVMContext &Ctx = M.getContext();
|
|
MMI.getContext().setDiagnosticHandler(
|
|
[&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
|
|
const SourceMgr &SrcMgr,
|
|
std::vector<const MDNode *> &LocInfos) {
|
|
unsigned LocCookie = 0;
|
|
if (IsInlineAsm)
|
|
LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
|
|
Ctx.diagnose(
|
|
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
|
|
});
|
|
return Result(MMI);
|
|
}
|