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 707524556c
commit 7bda195812
19 changed files with 150 additions and 170 deletions

View File

@ -18,7 +18,6 @@
#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H #ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H #define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include <memory> #include <memory>
@ -27,29 +26,30 @@ namespace llvm {
class StringRef; class StringRef;
class MIRParserImpl; class MIRParserImpl;
class MachineModuleInfo;
class SMDiagnostic; class SMDiagnostic;
/// This class initializes machine functions by applying the state loaded from /// This class initializes machine functions by applying the state loaded from
/// a MIR file. /// a MIR file.
class MIRParser : public MachineFunctionInitializer { class MIRParser {
std::unique_ptr<MIRParserImpl> Impl; std::unique_ptr<MIRParserImpl> Impl;
public: public:
MIRParser(std::unique_ptr<MIRParserImpl> Impl); MIRParser(std::unique_ptr<MIRParserImpl> Impl);
MIRParser(const MIRParser &) = delete; 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. /// A new, empty module is created if the LLVM IR isn't present.
/// Returns null if a parsing error occurred. /// \returns nullptr if a parsing error occurred.
std::unique_ptr<Module> parseLLVMModule(); std::unique_ptr<Module> parseIRModule();
/// Initialize the machine function to the state that's described in the MIR /// \brief Parses MachineFunctions in the MIR file and add them to the given
/// file. /// MachineModuleInfo \p MMI.
/// ///
/// Return true if error occurred. /// \returns true if an error occurred.
bool initializeMachineFunction(MachineFunction &MF) override; bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
}; };
/// This function is the main interface to the MIR serialization format parser. /// 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 CallInst;
class Function; class Function;
class MachineFunction; class MachineFunction;
class MachineFunctionInitializer;
class MMIAddrLabelMap; class MMIAddrLabelMap;
class Module; class Module;
class TargetMachine; class TargetMachine;
@ -126,7 +125,6 @@ class MachineModuleInfo : public ImmutablePass {
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details. /// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
bool UsesMorestackAddr; bool UsesMorestackAddr;
MachineFunctionInitializer *MFInitializer;
/// Maps IR Functions to their corresponding MachineFunctions. /// Maps IR Functions to their corresponding MachineFunctions.
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions; DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
/// Next unique number available for a MachineFunction. /// Next unique number available for a MachineFunction.
@ -150,14 +148,13 @@ public:
void setModule(const Module *M) { TheModule = M; } void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; } const Module *getModule() const { return TheModule; }
void setMachineFunctionInitializer(MachineFunctionInitializer *MFInit) {
MFInitializer = MFInit;
}
/// Returns the MachineFunction constructed for the IR function \p F. /// Returns the MachineFunction constructed for the IR function \p F.
/// Creates a new MachineFunction and runs the MachineFunctionInitializer /// Creates a new MachineFunction if none exists yet.
/// if none exists yet. MachineFunction &getOrCreateMachineFunction(const Function &F);
MachineFunction &getMachineFunction(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 /// Delete the MachineFunction \p MF and reset the link in the IR Function to
/// Machine Function map. /// Machine Function map.

View File

@ -25,7 +25,6 @@
namespace llvm { namespace llvm {
class GlobalValue; class GlobalValue;
class MachineFunctionInitializer;
class Mangler; class Mangler;
class MCAsmInfo; class MCAsmInfo;
class MCContext; class MCContext;
@ -227,8 +226,7 @@ public:
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType, PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr, bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr, AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr,
AnalysisID /*StopAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr) {
MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
return true; return true;
} }
@ -289,8 +287,7 @@ public:
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify = true, AnalysisID StartBefore = nullptr, bool DisableVerify = true, AnalysisID StartBefore = nullptr,
AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr, AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr,
AnalysisID StopAfter = nullptr, AnalysisID StopAfter = nullptr) override;
MachineFunctionInitializer *MFInitializer = nullptr) override;
/// Add passes to the specified pass manager to get machine code emitted with /// 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 /// 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, addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
bool DisableVerify, AnalysisID StartBefore, bool DisableVerify, AnalysisID StartBefore,
AnalysisID StartAfter, AnalysisID StopBefore, AnalysisID StartAfter, AnalysisID StopBefore,
AnalysisID StopAfter, AnalysisID StopAfter) {
MachineFunctionInitializer *MFInitializer = nullptr) {
// Targets may override createPassConfig to provide a target-specific // Targets may override createPassConfig to provide a target-specific
// subclass. // subclass.
TargetPassConfig *PassConfig = TM->createPassConfig(PM); TargetPassConfig *PassConfig = TM->createPassConfig(PM);
@ -107,7 +105,6 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
PassConfig->setDisableVerify(DisableVerify); PassConfig->setDisableVerify(DisableVerify);
PM.add(PassConfig); PM.add(PassConfig);
MachineModuleInfo *MMI = new MachineModuleInfo(TM); MachineModuleInfo *MMI = new MachineModuleInfo(TM);
MMI->setMachineFunctionInitializer(MFInitializer);
PM.add(MMI); PM.add(MMI);
if (PassConfig->addISelPasses()) if (PassConfig->addISelPasses())
@ -192,12 +189,11 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
bool LLVMTargetMachine::addPassesToEmitFile( bool LLVMTargetMachine::addPassesToEmitFile(
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter, bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
AnalysisID StopBefore, AnalysisID StopAfter, AnalysisID StopBefore, AnalysisID StopAfter) {
MachineFunctionInitializer *MFInitializer) {
// Add common CodeGen passes. // Add common CodeGen passes.
MCContext *Context = MCContext *Context =
addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter, addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter,
StopBefore, StopAfter, MFInitializer); StopBefore, StopAfter);
if (!Context) if (!Context)
return true; return true;

View File

@ -50,18 +50,24 @@ namespace llvm {
/// file. /// file.
class MIRParserImpl { class MIRParserImpl {
SourceMgr SM; SourceMgr SM;
yaml::Input In;
StringRef Filename; StringRef Filename;
LLVMContext &Context; LLVMContext &Context;
StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
SlotMapping IRSlots; SlotMapping IRSlots;
/// Maps from register class names to register classes. /// Maps from register class names to register classes.
Name2RegClassMap Names2RegClasses; Name2RegClassMap Names2RegClasses;
/// Maps from register bank names to register banks. /// Maps from register bank names to register banks.
Name2RegBankMap Names2RegBanks; 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: public:
MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename, MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
LLVMContext &Context); StringRef Filename, LLVMContext &Context);
void reportDiagnostic(const SMDiagnostic &Diag); void reportDiagnostic(const SMDiagnostic &Diag);
@ -85,22 +91,22 @@ public:
/// file. /// file.
/// ///
/// Return null if an error occurred. /// 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. /// 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. /// 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 /// Initialize the machine function to the state that's described in the MIR
/// file. /// file.
/// ///
/// Return true if error occurred. /// Return true if error occurred.
bool initializeMachineFunction(MachineFunction &MF); bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
MachineFunction &MF);
bool parseRegisterInfo(PerFunctionMIParsingState &PFS, bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF); const yaml::MachineFunction &YamlMF);
@ -144,9 +150,6 @@ private:
SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error, SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
SMRange SourceRange); SMRange SourceRange);
/// Create an empty function with the given name.
void createDummyFunction(StringRef Name, Module &M);
void initNames2RegClasses(const MachineFunction &MF); void initNames2RegClasses(const MachineFunction &MF);
void initNames2RegBanks(const MachineFunction &MF); void initNames2RegBanks(const MachineFunction &MF);
@ -166,10 +169,19 @@ private:
} // end namespace llvm } // end namespace llvm
static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
}
MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
StringRef Filename, LLVMContext &Context) StringRef Filename, LLVMContext &Context)
: SM(), Filename(Filename), Context(Context) { : SM(),
SM.AddNewSourceBuffer(std::move(Contents), SMLoc()); 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) { bool MIRParserImpl::error(const Twine &Message) {
@ -206,24 +218,16 @@ void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag)); Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
} }
static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { std::unique_ptr<Module> MIRParserImpl::parseIRModule() {
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);
if (!In.setCurrentDocument()) { if (!In.setCurrentDocument()) {
if (In.error()) if (In.error())
return nullptr; return nullptr;
// Create an empty module when the MIR file is empty. // Create an empty module when the MIR file is empty.
NoMIRDocuments = true;
return llvm::make_unique<Module>(Filename, Context); return llvm::make_unique<Module>(Filename, Context);
} }
std::unique_ptr<Module> M; std::unique_ptr<Module> M;
bool NoLLVMIR = false;
// Parse the block scalar manually so that we can return unique pointer // Parse the block scalar manually so that we can return unique pointer
// without having to go trough YAML traits. // without having to go trough YAML traits.
if (const auto *BSN = if (const auto *BSN =
@ -237,49 +241,68 @@ std::unique_ptr<Module> MIRParserImpl::parse() {
} }
In.nextDocument(); In.nextDocument();
if (!In.setCurrentDocument()) if (!In.setCurrentDocument())
return M; NoMIRDocuments = true;
} else { } else {
// Create an new, empty module. // Create an new, empty module.
M = llvm::make_unique<Module>(Filename, Context); M = llvm::make_unique<Module>(Filename, Context);
NoLLVMIR = true; NoLLVMIR = true;
} }
// Parse the machine functions.
do {
if (parseMachineFunction(In, *M, NoLLVMIR))
return nullptr;
In.nextDocument();
} while (In.setCurrentDocument());
return M; return M;
} }
bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M, bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
bool NoLLVMIR) { if (NoMIRDocuments)
auto MF = llvm::make_unique<yaml::MachineFunction>(); return false;
yaml::EmptyContext Ctx;
yaml::yamlize(In, *MF, false, Ctx); // Parse the machine functions.
if (In.error()) do {
return true; if (parseMachineFunction(M, MMI))
auto FunctionName = MF->Name; return true;
if (Functions.find(FunctionName) != Functions.end()) In.nextDocument();
return error(Twine("redefinition of machine function '") + FunctionName + } while (In.setCurrentDocument());
"'");
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");
return false; 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(); auto &Context = M.getContext();
Function *F = cast<Function>(M.getOrInsertFunction( Function *F = cast<Function>(M.getOrInsertFunction(
Name, FunctionType::get(Type::getVoidTy(Context), false))); Name, FunctionType::get(Type::getVoidTy(Context), false)));
BasicBlock *BB = BasicBlock::Create(Context, "entry", F); BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
new UnreachableInst(Context, BB); 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) { static bool isSSA(const MachineFunction &MF) {
@ -319,15 +342,12 @@ void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
Properties.set(MachineFunctionProperties::Property::NoVRegs); Properties.set(MachineFunctionProperties::Property::NoVRegs);
} }
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { bool
auto It = Functions.find(MF.getName()); MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
if (It == Functions.end()) MachineFunction &MF) {
return error(Twine("no machine function information for function '") +
MF.getName() + "' in the MIR file");
// TODO: Recreate the machine function. // TODO: Recreate the machine function.
initNames2RegClasses(MF); initNames2RegClasses(MF);
initNames2RegBanks(MF); initNames2RegBanks(MF);
const yaml::MachineFunction &YamlMF = *It->getValue();
if (YamlMF.Alignment) if (YamlMF.Alignment)
MF.setAlignment(YamlMF.Alignment); MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
@ -838,10 +858,12 @@ MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
MIRParser::~MIRParser() {} 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) { bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
return Impl->initializeMachineFunction(MF); return Impl->parseMachineFunctions(M, MMI);
} }
std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename, std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,

View File

@ -20,7 +20,6 @@
#include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h"
@ -52,8 +51,6 @@ static cl::opt<unsigned>
cl::desc("Force the alignment of all functions."), cl::desc("Force the alignment of all functions."),
cl::init(0), cl::Hidden); cl::init(0), cl::Hidden);
void MachineFunctionInitializer::anchor() {}
static const char *getPropertyName(MachineFunctionProperties::Property Prop) { static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
typedef MachineFunctionProperties::Property P; typedef MachineFunctionProperties::Property P;
switch(Prop) { switch(Prop) {

View File

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

View File

@ -13,7 +13,6 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/TinyPtrVector.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/Passes.h"
#include "llvm/IR/BasicBlock.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 // Shortcut for the common case where a sequence of MachineFunctionPasses
// all query for the same Function. // all query for the same Function.
if (LastRequest == &F) if (LastRequest == &F)
@ -273,10 +279,6 @@ MachineFunction &MachineModuleInfo::getMachineFunction(const Function &F) {
MF = new MachineFunction(&F, TM, NextFnNum++, *this); MF = new MachineFunction(&F, TM, NextFnNum++, *this);
// Update the set entry. // Update the set entry.
I.first->second.reset(MF); I.first->second.reset(MF);
if (MFInitializer)
if (MFInitializer->initializeMachineFunction(*MF))
report_fatal_error("Unable to initialize machine function");
} else { } else {
MF = I.first->second.get(); MF = I.first->second.get();
} }

View File

@ -1111,7 +1111,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
Builder.CreateRetVoid(); Builder.CreateRetVoid();
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
MachineFunction &MF = MMI.getMachineFunction(*F); MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock(); MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock();
const TargetSubtargetInfo &STI = MF.getSubtarget(); const TargetSubtargetInfo &STI = MF.getSubtarget();
const TargetInstrInfo &TII = *STI.getInstrInfo(); const TargetInstrInfo &TII = *STI.getInstrInfo();
@ -1207,7 +1207,7 @@ bool MachineOutliner::runOnModule(Module &M) {
return false; return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
const TargetSubtargetInfo &STI = MMI.getMachineFunction(*M.begin()) const TargetSubtargetInfo &STI = MMI.getOrCreateMachineFunction(*M.begin())
.getSubtarget(); .getSubtarget();
const TargetRegisterInfo *TRI = STI.getRegisterInfo(); const TargetRegisterInfo *TRI = STI.getRegisterInfo();
const TargetInstrInfo *TII = STI.getInstrInfo(); const TargetInstrInfo *TII = STI.getInstrInfo();
@ -1216,7 +1216,7 @@ bool MachineOutliner::runOnModule(Module &M) {
// Build instruction mappings for each function in the module. // Build instruction mappings for each function in the module.
for (Function &F : M) { for (Function &F : M) {
MachineFunction &MF = MMI.getMachineFunction(F); MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
// Is the function empty? Safe to outline from? // Is the function empty? Safe to outline from?
if (F.empty() || !TII->isFunctionSafeToOutlineFrom(MF)) if (F.empty() || !TII->isFunctionSafeToOutlineFrom(MF))

View File

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

View File

@ -18,6 +18,5 @@ body: |
liveins: %w0 liveins: %w0
; ERR: generic virtual registers must have a type ; ERR: generic virtual registers must have a type
; ERR-NEXT: %0 ; ERR-NEXT: %0
; ERR: Unable to initialize machine function
%0 = G_ADD i32 %w0, %w0 %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")) { if (StringRef(InputFilename).endswith_lower(".mir")) {
MIR = createMIRParserFromFile(InputFilename, Err, Context); MIR = createMIRParserFromFile(InputFilename, Err, Context);
if (MIR) if (MIR)
M = MIR->parseLLVMModule(); M = MIR->parseIRModule();
} else } else
M = parseIRFile(InputFilename, Err, Context); M = parseIRFile(InputFilename, Err, Context);
if (!M) { if (!M) {
@ -540,7 +540,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
TPC.setDisableVerify(NoVerify); TPC.setDisableVerify(NoVerify);
PM.add(&TPC); PM.add(&TPC);
MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM); MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM);
MMI->setMachineFunctionInitializer(MIR.get()); if (MIR->parseMachineFunctions(*M, *MMI))
return 1;
PM.add(MMI); PM.add(MMI);
TPC.printAndVerify(""); TPC.printAndVerify("");

View File

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

View File

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