]> granicus.if.org Git - llvm/commitdiff
CodeGen: Refactor MIR parsing
authorMatthias Braun <matze@braunis.de>
Tue, 6 Jun 2017 00:44:35 +0000 (00:44 +0000)
committerMatthias Braun <matze@braunis.de>
Tue, 6 Jun 2017 00:44:35 +0000 (00:44 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304758 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/llvm/CodeGen/MIRParser/MIRParser.h
include/llvm/CodeGen/MachineFunctionInitializer.h [deleted file]
include/llvm/CodeGen/MachineModuleInfo.h
include/llvm/Target/TargetMachine.h
lib/CodeGen/LLVMTargetMachine.cpp
lib/CodeGen/MIRParser/MIRParser.cpp
lib/CodeGen/MachineFunction.cpp
lib/CodeGen/MachineFunctionPass.cpp
lib/CodeGen/MachineModuleInfo.cpp
lib/CodeGen/MachineOutliner.cpp
test/CodeGen/MIR/AArch64/generic-virtual-registers-error.mir
test/CodeGen/MIR/AArch64/generic-virtual-registers-with-regbank-error.mir
test/CodeGen/MIR/Generic/function-missing-machine-function.mir [deleted file]
test/CodeGen/MIR/X86/empty0.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/empty1.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/empty2.mir [new file with mode: 0644]
tools/llc/llc.cpp
unittests/MI/LiveIntervalTest.cpp
unittests/Target/AArch64/InstSizes.cpp

index dd0780397f4293db4301a92eee9c02079fd06b2b..b631a8c0122a290f4ce30572d6e28d4394e23879 100644 (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.
diff --git a/include/llvm/CodeGen/MachineFunctionInitializer.h b/include/llvm/CodeGen/MachineFunctionInitializer.h
deleted file mode 100644 (file)
index 0fbcb48..0000000
+++ /dev/null
@@ -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
index d4ac58c3bd22c90cd93d139ac28523b5b8f3c49c..d64941a9e725a27c8e5379c93edce41cf4dad265 100644 (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.
index d68bd3543dd34fdd0773cbbd0c165d70da6e7c2d..933c6c87b0beaf4c6bd5030dcdcde83672403dae 100644 (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
index 66e6e7abc067a71cfc4948a9e6bf75dbb482da41..35c4dfae008f70d09dda9fc4c4f1d9db34b5800a 100644 (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;
 
index ff12297e3fc67e476bdc3810f673279d400c75f6..cdeba007458f9b1b26c0ff42f49b3b0747e2a9e4 100644 (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;
   }
+  return M;
+}
+
+bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
+  if (NoMIRDocuments)
+    return false;
 
   // Parse the machine functions.
   do {
-    if (parseMachineFunction(In, *M, NoLLVMIR))
-      return nullptr;
+    if (parseMachineFunction(M, MMI))
+      return true;
     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");
   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,
index ac4ccb81b884ad9dbd3fe946b89b79a201bedb85..bbdae6e1a49e5f5353316b611ab4d755ea5c7143 100644 (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) {
index 2265676ff8b1445836263891339abd025a8f1ba5..5ffe330061313f9d0bd5080b8112722ed2f54f79 100644 (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();
 
index c1b72430e60532de2e17d92697d2daaa9b731953..62fa1f9444f786a385e6f40ae0fb111eb8908b13 100644 (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();
   }
index 9ea3c00a2fc488c3f874077768709fb7f213cbc2..fd6b2427891d10e4f3fa1d28003ab96c2392e51a 100644 (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))
index d63c2ef6e8713ea2a974da5635bc5afb9d1c8e6c..af785bcb10a9b1522aca8937e5a452d6084dc65d 100644 (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
 ...
index e331179773d61f0b06439bbfe4e089505a313642..f177b91da559fc223a5a913c89ae38b9fb4ff377 100644 (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
 ...
diff --git a/test/CodeGen/MIR/Generic/function-missing-machine-function.mir b/test/CodeGen/MIR/Generic/function-missing-machine-function.mir
deleted file mode 100644 (file)
index f3a8348..0000000
+++ /dev/null
@@ -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
-  }
-
-...
diff --git a/test/CodeGen/MIR/X86/empty0.mir b/test/CodeGen/MIR/X86/empty0.mir
new file mode 100644 (file)
index 0000000..4431af7
--- /dev/null
@@ -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: ...
diff --git a/test/CodeGen/MIR/X86/empty1.mir b/test/CodeGen/MIR/X86/empty1.mir
new file mode 100644 (file)
index 0000000..d80b0cd
--- /dev/null
@@ -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: ...
diff --git a/test/CodeGen/MIR/X86/empty2.mir b/test/CodeGen/MIR/X86/empty2.mir
new file mode 100644 (file)
index 0000000..7495807
--- /dev/null
@@ -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: ...
index 9c42f66b89317601cf8923288b316e9cdfbaff18..10fb9f623325d2e63402e8c058d182a6eb81bf4c 100644 (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("");
 
index 026fb42d345f75300190f9d4baf2ab8d2280e203..a37d6ed8f630d8258678cb99b1b39ce4b871b88f 100644 (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));
 
index 22b47c6852ab62c17a38b036492ac7ecd99e453c..5ee5e9c048acae920e85aaa1faf698ab4c21752a 100644 (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);
 }