diff options
author | Matthias Braun <matze@braunis.de> | 2016-08-23 20:58:29 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2016-08-23 20:58:29 +0000 |
commit | 4c1f1f120c9da460a7b1d1f24936499d8caeae11 (patch) | |
tree | 666d4ef636a0d25b6210ac0b3a3b377b026f7275 /llvm/lib/CodeGen/MachineModuleInfo.cpp | |
parent | 54690dcdb00d73e7136aade84949666a7047f8cc (diff) | |
download | bcm5719-llvm-4c1f1f120c9da460a7b1d1f24936499d8caeae11.tar.gz bcm5719-llvm-4c1f1f120c9da460a7b1d1f24936499d8caeae11.zip |
CodeGen: Remove MachineFunctionAnalysis => Enable (Machine)ModulePasses
Re-apply this commit with the deletion of a MachineFunction delegated to
a separate pass to avoid use after free when doing this directly in
AsmPrinter.
This patch removes the MachineFunctionAnalysis. Instead we keep a
map from IR Function to MachineFunction in the MachineModuleInfo.
This allows the insertion of ModulePasses into the codegen pipeline
without breaking it because the MachineFunctionAnalysis gets dropped
before a module pass.
Peak memory should stay unchanged without a ModulePass in the codegen
pipeline: Previously the MachineFunction was freed at the end of a codegen
function pipeline because the MachineFunctionAnalysis was dropped; With
this patch the MachineFunction is freed after the AsmPrinter has
finished.
Differential Revision: http://reviews.llvm.org/D23736
llvm-svn: 279564
Diffstat (limited to 'llvm/lib/CodeGen/MachineModuleInfo.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineModuleInfo.cpp | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp index 244e3fbc4e8..e5fc5cd5903 100644 --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -13,6 +13,7 @@ #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionInitializer.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Constants.h" @@ -186,15 +187,19 @@ void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { //===----------------------------------------------------------------------===// -MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI, +MachineModuleInfo::MachineModuleInfo(const TargetMachine &TM, + const MCAsmInfo &MAI, const MCRegisterInfo &MRI, - const MCObjectFileInfo *MOFI) - : ImmutablePass(ID), Context(&MAI, &MRI, MOFI, nullptr, false) { + const MCObjectFileInfo *MOFI, + MachineFunctionInitializer *MFI) + : ImmutablePass(ID), TM(TM), Context(&MAI, &MRI, MOFI, nullptr, false), + MFInitializer(MFI) { initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); } MachineModuleInfo::MachineModuleInfo() - : ImmutablePass(ID), Context(nullptr, nullptr, nullptr) { + : ImmutablePass(ID), TM(*((TargetMachine*)nullptr)), + Context(nullptr, nullptr, nullptr) { llvm_unreachable("This MachineModuleInfo constructor should never be called, " "MMI should always be explicitly constructed by " "LLVMTargetMachine"); @@ -213,7 +218,7 @@ bool MachineModuleInfo::doInitialization(Module &M) { DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false; PersonalityTypeCache = EHPersonality::Unknown; AddrLabelSymbols = nullptr; - TheModule = nullptr; + TheModule = &M; return false; } @@ -461,3 +466,63 @@ try_next:; FilterIds.push_back(0); // terminator return FilterID; } + +MachineFunction &MachineModuleInfo::getMachineFunction(const 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. + MF = new MachineFunction(&F, TM, NextFnNum++, *this); + // Update the set entry. + I.first->second.reset(MF); + + if (MFInitializer) + if (MFInitializer->initializeMachineFunction(*MF)) + report_fatal_error("Unable to initialize machine function"); + } else { + MF = I.first->second.get(); + } + + LastRequest = &F; + LastResult = MF; + return *MF; +} + +void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { + MachineFunctions.erase(&F); + LastRequest = nullptr; + LastResult = nullptr; +} + +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<MachineModuleInfo>(); + AU.addPreserved<MachineModuleInfo>(); + } + + bool runOnFunction(Function &F) override { + MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); + MMI.deleteMachineFunctionFor(F); + return true; + } +}; +char FreeMachineFunction::ID; +} // end anonymous namespace + +namespace llvm { +FunctionPass *createFreeMachineFunctionPass() { + return new FreeMachineFunction(); +} +} // end namespace llvm |