1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

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
This commit is contained in:
Matthias Braun 2017-06-06 00:44:35 +00:00
parent 188048610f
commit 17b01651c8
19 changed files with 150 additions and 170 deletions

View File

@ -18,7 +18,6 @@
#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
@ -27,29 +26,30 @@ namespace llvm {
class StringRef;
class MIRParserImpl;
class MachineModuleInfo;
class SMDiagnostic;
/// This class initializes machine functions by applying the state loaded from
/// a MIR file.
class MIRParser : public MachineFunctionInitializer {
class MIRParser {
std::unique_ptr<MIRParserImpl> Impl;
public:
MIRParser(std::unique_ptr<MIRParserImpl> Impl);
MIRParser(const MIRParser &) = delete;
~MIRParser() override;
~MIRParser();
/// Parse the optional LLVM IR module that's embedded in the MIR file.
/// Parses the optional LLVM IR module in the MIR file.
///
/// A new, empty module is created if the LLVM IR isn't present.
/// Returns null if a parsing error occurred.
std::unique_ptr<Module> parseLLVMModule();
/// \returns nullptr if a parsing error occurred.
std::unique_ptr<Module> parseIRModule();
/// Initialize the machine function to the state that's described in the MIR
/// file.
/// \brief Parses MachineFunctions in the MIR file and add them to the given
/// MachineModuleInfo \p MMI.
///
/// Return true if error occurred.
bool initializeMachineFunction(MachineFunction &MF) override;
/// \returns true if an error occurred.
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
};
/// This function is the main interface to the MIR serialization format parser.

View File

@ -1,38 +0,0 @@
//=- MachineFunctionInitializer.h - machine function initializer --*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares an interface that allows custom machine function
// initialization.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
#define LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
namespace llvm {
class MachineFunction;
/// This interface provides a way to initialize machine functions after they are
/// created by the machine function analysis pass.
class MachineFunctionInitializer {
virtual void anchor();
public:
virtual ~MachineFunctionInitializer() = default;
/// Initialize the machine function.
///
/// Return true if error occurred.
virtual bool initializeMachineFunction(MachineFunction &MF) = 0;
};
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H

View File

@ -47,7 +47,6 @@ class BasicBlock;
class CallInst;
class Function;
class MachineFunction;
class MachineFunctionInitializer;
class MMIAddrLabelMap;
class Module;
class TargetMachine;
@ -126,7 +125,6 @@ class MachineModuleInfo : public ImmutablePass {
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
bool UsesMorestackAddr;
MachineFunctionInitializer *MFInitializer;
/// Maps IR Functions to their corresponding MachineFunctions.
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
/// Next unique number available for a MachineFunction.
@ -150,14 +148,13 @@ public:
void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; }
void setMachineFunctionInitializer(MachineFunctionInitializer *MFInit) {
MFInitializer = MFInit;
}
/// Returns the MachineFunction constructed for the IR function \p F.
/// Creates a new MachineFunction and runs the MachineFunctionInitializer
/// if none exists yet.
MachineFunction &getMachineFunction(const Function &F);
/// Creates a new MachineFunction if none exists yet.
MachineFunction &getOrCreateMachineFunction(const Function &F);
/// \bried Returns the MachineFunction associated to IR function \p F if there
/// is one, otherwise nullptr.
MachineFunction *getMachineFunction(const Function &F) const;
/// Delete the MachineFunction \p MF and reset the link in the IR Function to
/// Machine Function map.

View File

@ -25,7 +25,6 @@
namespace llvm {
class GlobalValue;
class MachineFunctionInitializer;
class Mangler;
class MCAsmInfo;
class MCContext;
@ -227,8 +226,7 @@ public:
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr,
AnalysisID /*StopAfter*/ = nullptr,
MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
AnalysisID /*StopAfter*/ = nullptr) {
return true;
}
@ -289,8 +287,7 @@ public:
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify = true, AnalysisID StartBefore = nullptr,
AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr,
AnalysisID StopAfter = nullptr,
MachineFunctionInitializer *MFInitializer = nullptr) override;
AnalysisID StopAfter = nullptr) override;
/// Add passes to the specified pass manager to get machine code emitted with
/// the MCJIT. This method returns true if machine code is not supported. It

View File

@ -95,9 +95,7 @@ static MCContext *
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 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
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::addAsmPrinter(PassManagerBase &PM,
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;

View File

@ -50,18 +50,24 @@ namespace llvm {
/// 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 @@ public:
/// 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 @@ private:
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 @@ private:
} // 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 @@ void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
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 @@ std::unique_ptr<Module> MIRParserImpl::parse() {
}
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 @@ void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
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<MIRParserImpl> Impl)
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,

View File

@ -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 @@ static cl::opt<unsigned>
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) {

View File

@ -42,7 +42,7 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
MachineFunction &MF = MMI.getMachineFunction(F);
MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
MachineFunctionProperties &MFProps = MF.getProperties();

View File

@ -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 @@ void MachineModuleInfo::addPersonality(const Function *Personality) {
/// \}
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 @@ MachineFunction &MachineModuleInfo::getMachineFunction(const Function &F) {
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();
}

View File

@ -1111,7 +1111,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
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 @@ bool MachineOutliner::runOnModule(Module &M) {
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 @@ bool MachineOutliner::runOnModule(Module &M) {
// 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))

View File

@ -17,6 +17,5 @@ body: |
liveins: %w0
; ERR: generic virtual registers must have a type
; ERR-NEXT: %0
; ERR: Unable to initialize machine function
%0 = G_ADD i32 %w0, %w0
...

View File

@ -18,6 +18,5 @@ body: |
liveins: %w0
; ERR: generic virtual registers must have a type
; ERR-NEXT: %0
; ERR: Unable to initialize machine function
%0 = G_ADD i32 %w0, %w0
...

View File

@ -1,13 +0,0 @@
# RUN: not llc -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
# This test verifies that an error is reported when a MIR file has some
# function but is missing a corresponding machine function.
# CHECK: no machine function information for function 'foo' in the MIR file
--- |
define i32 @foo() {
ret i32 0
}
...

View File

@ -0,0 +1,6 @@
# RUN: llc -run-pass none -o - %s | FileCheck %s
# Make sure empty files don't crash us
# CHECK: --- |
# ... moduleid, sourcefilename stuff here ..
# CHECK: target datalayout =
# CHECK: ...

View File

@ -0,0 +1,8 @@
# RUN: llc -run-pass none -o - %s | FileCheck %s
# Make sure empty files don't crash us
--- |
...
# CHECK: --- |
# ... moduleid, sourcefilename stuff here ..
# CHECK: target datalayout =
# CHECK: ...

View File

@ -0,0 +1,8 @@
# RUN: llc -run-pass none -o - %s | FileCheck %s
# Make sure empty files don't crash us
---
...
# CHECK: --- |
# ... moduleid, sourcefilename stuff here ..
# CHECK: target datalayout =
# CHECK: ...

View File

@ -401,7 +401,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
if (StringRef(InputFilename).endswith_lower(".mir")) {
MIR = createMIRParserFromFile(InputFilename, Err, Context);
if (MIR)
M = MIR->parseLLVMModule();
M = MIR->parseIRModule();
} else
M = parseIRFile(InputFilename, Err, Context);
if (!M) {
@ -540,7 +540,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
TPC.setDisableVerify(NoVerify);
PM.add(&TPC);
MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM);
MMI->setMachineFunctionInitializer(MIR.get());
if (MIR->parseMachineFunctions(*M, *MMI))
return 1;
PM.add(MMI);
TPC.printAndVerify("");

View File

@ -59,18 +59,15 @@ std::unique_ptr<Module> parseMIR(LLVMContext &Context,
if (!MIR)
return nullptr;
std::unique_ptr<Module> M = MIR->parseLLVMModule();
std::unique_ptr<Module> M = MIR->parseIRModule();
if (!M)
return nullptr;
M->setDataLayout(TM.createDataLayout());
Function *F = M->getFunction(FuncName);
if (!F)
return nullptr;
MachineModuleInfo *MMI = new MachineModuleInfo(&TM);
MMI->setMachineFunctionInitializer(MIR.get());
if (MIR->parseMachineFunctions(*M, *MMI))
return nullptr;
PM.add(MMI);
return M;
@ -154,6 +151,7 @@ body: |
std::unique_ptr<MIRParser> MIR;
std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
"func");
assert(M && "MIR parsing successfull");
PM.add(new TestPass(T));

View File

@ -60,18 +60,19 @@ void runChecks(
createMIRParser(std::move(MBuffer), Context);
assert(MParser && "Couldn't create MIR parser");
std::unique_ptr<Module> M = MParser->parseLLVMModule();
std::unique_ptr<Module> M = MParser->parseIRModule();
assert(M && "Couldn't parse module");
M->setTargetTriple(TM->getTargetTriple().getTriple());
M->setDataLayout(TM->createDataLayout());
MachineModuleInfo MMI(TM);
bool Res = MParser->parseMachineFunctions(*M, MMI);
assert(!Res && "Couldn't parse MIR functions");
auto F = M->getFunction("sizes");
assert(F && "Couldn't find intended function");
MachineModuleInfo MMI(TM);
MMI.setMachineFunctionInitializer(MParser.get());
auto &MF = MMI.getMachineFunction(*F);
auto &MF = MMI.getOrCreateMachineFunction(*F);
Checks(*II, MF);
}