CodeGen: Refactor MIR parsing
When parsing .mir files immediately construct the MachineFunctions and
put them into MachineModuleInfo.
This allows us to get rid of the delayed construction (and delayed error
reporting) through the MachineFunctionInitialzier interface.
Differential Revision: https://reviews.llvm.org/D33809
llvm-svn: 304758
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
index 66e6e7a..35c4dfa 100644
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
@@ -95,9 +95,7 @@
addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
bool DisableVerify, AnalysisID StartBefore,
AnalysisID StartAfter, AnalysisID StopBefore,
- AnalysisID StopAfter,
- MachineFunctionInitializer *MFInitializer = nullptr) {
-
+ AnalysisID StopAfter) {
// Targets may override createPassConfig to provide a target-specific
// subclass.
TargetPassConfig *PassConfig = TM->createPassConfig(PM);
@@ -107,7 +105,6 @@
PassConfig->setDisableVerify(DisableVerify);
PM.add(PassConfig);
MachineModuleInfo *MMI = new MachineModuleInfo(TM);
- MMI->setMachineFunctionInitializer(MFInitializer);
PM.add(MMI);
if (PassConfig->addISelPasses())
@@ -192,12 +189,11 @@
bool LLVMTargetMachine::addPassesToEmitFile(
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
- AnalysisID StopBefore, AnalysisID StopAfter,
- MachineFunctionInitializer *MFInitializer) {
+ AnalysisID StopBefore, AnalysisID StopAfter) {
// Add common CodeGen passes.
MCContext *Context =
addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter,
- StopBefore, StopAfter, MFInitializer);
+ StopBefore, StopAfter);
if (!Context)
return true;
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index ff12297..cdeba00 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -50,18 +50,24 @@
/// file.
class MIRParserImpl {
SourceMgr SM;
+ yaml::Input In;
StringRef Filename;
LLVMContext &Context;
- StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
SlotMapping IRSlots;
/// Maps from register class names to register classes.
Name2RegClassMap Names2RegClasses;
/// Maps from register bank names to register banks.
Name2RegBankMap Names2RegBanks;
+ /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
+ /// created and inserted into the given module when this is true.
+ bool NoLLVMIR = false;
+ /// True when a well formed MIR file does not contain any MIR/machine function
+ /// parts.
+ bool NoMIRDocuments = false;
public:
- MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
- LLVMContext &Context);
+ MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
+ StringRef Filename, LLVMContext &Context);
void reportDiagnostic(const SMDiagnostic &Diag);
@@ -85,22 +91,22 @@
/// file.
///
/// Return null if an error occurred.
- std::unique_ptr<Module> parse();
+ std::unique_ptr<Module> parseIRModule();
+
+ bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
/// Parse the machine function in the current YAML document.
///
- /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
- /// A dummy IR function is created and inserted into the given module when
- /// this parameter is true.
///
/// Return true if an error occurred.
- bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
+ bool parseMachineFunction(Module &M, MachineModuleInfo &MMI);
/// Initialize the machine function to the state that's described in the MIR
/// file.
///
/// Return true if error occurred.
- bool initializeMachineFunction(MachineFunction &MF);
+ bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
+ MachineFunction &MF);
bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF);
@@ -144,9 +150,6 @@
SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
SMRange SourceRange);
- /// Create an empty function with the given name.
- void createDummyFunction(StringRef Name, Module &M);
-
void initNames2RegClasses(const MachineFunction &MF);
void initNames2RegBanks(const MachineFunction &MF);
@@ -166,10 +169,19 @@
} // end namespace llvm
+static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
+ reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
+}
+
MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
StringRef Filename, LLVMContext &Context)
- : SM(), Filename(Filename), Context(Context) {
- SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
+ : SM(),
+ In(SM.getMemoryBuffer(
+ SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))->getBuffer(),
+ nullptr, handleYAMLDiag, this),
+ Filename(Filename),
+ Context(Context) {
+ In.setContext(&In);
}
bool MIRParserImpl::error(const Twine &Message) {
@@ -206,24 +218,16 @@
Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
}
-static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
- reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
-}
-
-std::unique_ptr<Module> MIRParserImpl::parse() {
- yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
- /*Ctxt=*/nullptr, handleYAMLDiag, this);
- In.setContext(&In);
-
+std::unique_ptr<Module> MIRParserImpl::parseIRModule() {
if (!In.setCurrentDocument()) {
if (In.error())
return nullptr;
// Create an empty module when the MIR file is empty.
+ NoMIRDocuments = true;
return llvm::make_unique<Module>(Filename, Context);
}
std::unique_ptr<Module> M;
- bool NoLLVMIR = false;
// Parse the block scalar manually so that we can return unique pointer
// without having to go trough YAML traits.
if (const auto *BSN =
@@ -237,49 +241,68 @@
}
In.nextDocument();
if (!In.setCurrentDocument())
- return M;
+ NoMIRDocuments = true;
} else {
// Create an new, empty module.
M = llvm::make_unique<Module>(Filename, Context);
NoLLVMIR = true;
}
-
- // Parse the machine functions.
- do {
- if (parseMachineFunction(In, *M, NoLLVMIR))
- return nullptr;
- In.nextDocument();
- } while (In.setCurrentDocument());
-
return M;
}
-bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
- bool NoLLVMIR) {
- auto MF = llvm::make_unique<yaml::MachineFunction>();
- yaml::EmptyContext Ctx;
- yaml::yamlize(In, *MF, false, Ctx);
- if (In.error())
- return true;
- auto FunctionName = MF->Name;
- if (Functions.find(FunctionName) != Functions.end())
- return error(Twine("redefinition of machine function '") + FunctionName +
- "'");
- Functions.insert(std::make_pair(FunctionName, std::move(MF)));
- if (NoLLVMIR)
- createDummyFunction(FunctionName, M);
- else if (!M.getFunction(FunctionName))
- return error(Twine("function '") + FunctionName +
- "' isn't defined in the provided LLVM IR");
+bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
+ if (NoMIRDocuments)
+ return false;
+
+ // Parse the machine functions.
+ do {
+ if (parseMachineFunction(M, MMI))
+ return true;
+ In.nextDocument();
+ } while (In.setCurrentDocument());
+
return false;
}
-void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
+/// Create an empty function with the given name.
+static Function *createDummyFunction(StringRef Name, Module &M) {
auto &Context = M.getContext();
Function *F = cast<Function>(M.getOrInsertFunction(
Name, FunctionType::get(Type::getVoidTy(Context), false)));
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
new UnreachableInst(Context, BB);
+ return F;
+}
+
+bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
+ // Parse the yaml.
+ yaml::MachineFunction YamlMF;
+ yaml::EmptyContext Ctx;
+ yaml::yamlize(In, YamlMF, false, Ctx);
+ if (In.error())
+ return true;
+
+ // Search for the corresponding IR function.
+ StringRef FunctionName = YamlMF.Name;
+ Function *F = M.getFunction(FunctionName);
+ if (!F) {
+ if (NoLLVMIR) {
+ F = createDummyFunction(FunctionName, M);
+ } else {
+ return error(Twine("function '") + FunctionName +
+ "' isn't defined in the provided LLVM IR");
+ }
+ }
+ if (MMI.getMachineFunction(*F) != nullptr)
+ return error(Twine("redefinition of machine function '") + FunctionName +
+ "'");
+
+ // Create the MachineFunction.
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
+ if (initializeMachineFunction(YamlMF, MF))
+ return true;
+
+ return false;
}
static bool isSSA(const MachineFunction &MF) {
@@ -319,15 +342,12 @@
Properties.set(MachineFunctionProperties::Property::NoVRegs);
}
-bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
- auto It = Functions.find(MF.getName());
- if (It == Functions.end())
- return error(Twine("no machine function information for function '") +
- MF.getName() + "' in the MIR file");
+bool
+MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
+ MachineFunction &MF) {
// TODO: Recreate the machine function.
initNames2RegClasses(MF);
initNames2RegBanks(MF);
- const yaml::MachineFunction &YamlMF = *It->getValue();
if (YamlMF.Alignment)
MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
@@ -838,10 +858,12 @@
MIRParser::~MIRParser() {}
-std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
+std::unique_ptr<Module> MIRParser::parseIRModule() {
+ return Impl->parseIRModule();
+}
-bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
- return Impl->initializeMachineFunction(MF);
+bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
+ return Impl->parseMachineFunctions(M, MMI);
}
std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index ac4ccb8..bbdae6e 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -20,7 +20,6 @@
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
@@ -52,8 +51,6 @@
cl::desc("Force the alignment of all functions."),
cl::init(0), cl::Hidden);
-void MachineFunctionInitializer::anchor() {}
-
static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
typedef MachineFunctionProperties::Property P;
switch(Prop) {
diff --git a/llvm/lib/CodeGen/MachineFunctionPass.cpp b/llvm/lib/CodeGen/MachineFunctionPass.cpp
index 2265676..5ffe330 100644
--- a/llvm/lib/CodeGen/MachineFunctionPass.cpp
+++ b/llvm/lib/CodeGen/MachineFunctionPass.cpp
@@ -42,7 +42,7 @@
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
- MachineFunction &MF = MMI.getMachineFunction(F);
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
MachineFunctionProperties &MFProps = MF.getProperties();
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index c1b7243..62fa1f94 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -13,7 +13,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/BasicBlock.h"
@@ -259,7 +258,14 @@
/// \}
-MachineFunction &MachineModuleInfo::getMachineFunction(const Function &F) {
+MachineFunction *
+MachineModuleInfo::getMachineFunction(const Function &F) const {
+ auto I = MachineFunctions.find(&F);
+ return I != MachineFunctions.end() ? I->second.get() : nullptr;
+}
+
+MachineFunction &
+MachineModuleInfo::getOrCreateMachineFunction(const Function &F) {
// Shortcut for the common case where a sequence of MachineFunctionPasses
// all query for the same Function.
if (LastRequest == &F)
@@ -273,10 +279,6 @@
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();
}
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 9ea3c00..fd6b242 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -1111,7 +1111,7 @@
Builder.CreateRetVoid();
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
- MachineFunction &MF = MMI.getMachineFunction(*F);
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock();
const TargetSubtargetInfo &STI = MF.getSubtarget();
const TargetInstrInfo &TII = *STI.getInstrInfo();
@@ -1207,7 +1207,7 @@
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
- const TargetSubtargetInfo &STI = MMI.getMachineFunction(*M.begin())
+ const TargetSubtargetInfo &STI = MMI.getOrCreateMachineFunction(*M.begin())
.getSubtarget();
const TargetRegisterInfo *TRI = STI.getRegisterInfo();
const TargetInstrInfo *TII = STI.getInstrInfo();
@@ -1216,7 +1216,7 @@
// Build instruction mappings for each function in the module.
for (Function &F : M) {
- MachineFunction &MF = MMI.getMachineFunction(F);
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
// Is the function empty? Safe to outline from?
if (F.empty() || !TII->isFunctionSafeToOutlineFrom(MF))