CodeGen: Remove MachineFunctionAnalysis => Enable (Machine)ModulePasses
Re-apply this patch, hopefully I will get away without any warnings in the constructor now. 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: 279602
This commit is contained in:
@@ -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"
|
||||
@@ -189,8 +190,9 @@ void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
|
||||
: ImmutablePass(ID), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
|
||||
TM->getObjFileLowering(), nullptr, false) {
|
||||
: ImmutablePass(ID), TM(*TM),
|
||||
Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
|
||||
TM->getObjFileLowering(), nullptr, false) {
|
||||
initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
@@ -207,7 +209,7 @@ bool MachineModuleInfo::doInitialization(Module &M) {
|
||||
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
|
||||
PersonalityTypeCache = EHPersonality::Unknown;
|
||||
AddrLabelSymbols = nullptr;
|
||||
TheModule = nullptr;
|
||||
TheModule = &M;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -455,3 +457,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
|
||||
|
||||
Reference in New Issue
Block a user