#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>
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.
+++ /dev/null
-//=- 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
class CallInst;
class Function;
class MachineFunction;
-class MachineFunctionInitializer;
class MMIAddrLabelMap;
class Module;
class TargetMachine;
/// 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.
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.
namespace llvm {
class GlobalValue;
-class MachineFunctionInitializer;
class Mangler;
class MCAsmInfo;
class MCContext;
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;
}
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
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);
PassConfig->setDisableVerify(DisableVerify);
PM.add(PassConfig);
MachineModuleInfo *MMI = new MachineModuleInfo(TM);
- MMI->setMachineFunctionInitializer(MFInitializer);
PM.add(MMI);
if (PassConfig->addISelPasses())
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;
/// 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);
/// 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);
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);
} // 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) {
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 =
}
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) {
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);
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,
#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"
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) {
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
- MachineFunction &MF = MMI.getMachineFunction(F);
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
MachineFunctionProperties &MFProps = MF.getProperties();
#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"
/// \}
-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)
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();
}
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();
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();
// 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))
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
...
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
...
+++ /dev/null
-# 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
- }
-
-...
--- /dev/null
+# 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: ...
--- /dev/null
+# 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: ...
--- /dev/null
+# 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: ...
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) {
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("");
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;
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));
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);
}