Skip to content

Commit

Permalink
MIR Serialization: Connect the machine function analysis pass to the …
Browse files Browse the repository at this point in the history
…MIR parser.

This commit connects the machine function analysis pass (which creates machine
functions) to the MIR parser, which will initialize the machine functions 
with the state from the MIR file and reconstruct the machine IR.

This commit introduces a new interface called 'MachineFunctionInitializer',
which can be used to provide custom initialization for the machine functions.

This commit also introduces a new diagnostic class called 
'DiagnosticInfoMIRParser' which is used for MIR parsing errors.
This commit modifies the default diagnostic handling in LLVMContext - now the
the diagnostics are printed directly into llvm::errs() so that the MIR parsing 
errors can be printed with colours.  

Reviewers: Justin Bogner

Differential Revision: http://reviews.llvm.org/D9928

llvm-svn: 239753
  • Loading branch information
hyp committed Jun 15, 2015
1 parent 49e9010 commit 735c47e
Showing 22 changed files with 311 additions and 104 deletions.
51 changes: 40 additions & 11 deletions llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
Original file line number Diff line number Diff line change
@@ -19,33 +19,62 @@
#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H

#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>

namespace llvm {

class MIRParserImpl;
class SMDiagnostic;

/// This class initializes machine functions by applying the state loaded from
/// a MIR file.
class MIRParser : public MachineFunctionInitializer {
std::unique_ptr<MIRParserImpl> Impl;

public:
MIRParser(std::unique_ptr<MIRParserImpl> Impl);
MIRParser(const MIRParser &) = delete;
~MIRParser();

/// Parse the optional LLVM IR module that's embedded 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();

/// Initialize the machine function to the state that's described in the MIR
/// file.
///
/// Return true if error occurred.
bool initializeMachineFunction(MachineFunction &MF) override;
};

/// This function is the main interface to the MIR serialization format parser.
///
/// It reads a YAML file that has an optional LLVM IR and returns an LLVM
/// module.
/// It reads in a MIR file and returns a MIR parser that can parse the embedded
/// LLVM IR module and initialize the machine functions by parsing the machine
/// function's state.
///
/// \param Filename - The name of the file to parse.
/// \param Error - Error result info.
/// \param Context - Context in which to allocate globals info.
std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error,
LLVMContext &Context);
/// \param Context - Context which will be used for the parsed LLVM IR module.
std::unique_ptr<MIRParser> createMIRParserFromFile(StringRef Filename,
SMDiagnostic &Error,
LLVMContext &Context);

/// This function is another interface to the MIR serialization format parser.
///
/// It parses the optional LLVM IR in the given buffer, and returns an LLVM
/// module.
/// It returns a MIR parser that works with the given memory buffer and that can
/// parse the embedded LLVM IR module and initialize the machine functions by
/// parsing the machine function's state.
///
/// \param Contents - The MemoryBuffer containing the machine level IR.
/// \param Error - Error result info.
/// \param Context - Context in which to allocate globals info.
std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents,
SMDiagnostic &Error, LLVMContext &Context);
/// \param Context - Context which will be used for the parsed LLVM IR module.
std::unique_ptr<MIRParser>
createMIRParser(std::unique_ptr<MemoryBuffer> Contents, LLVMContext &Context);

} // end namespace llvm

6 changes: 5 additions & 1 deletion llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
namespace llvm {

class MachineFunction;
class MachineFunctionInitializer;
class TargetMachine;

/// MachineFunctionAnalysis - This class is a Pass that manages a
@@ -28,9 +29,12 @@ struct MachineFunctionAnalysis : public FunctionPass {
const TargetMachine &TM;
MachineFunction *MF;
unsigned NextFnNum;
MachineFunctionInitializer *MFInitializer;

public:
static char ID;
explicit MachineFunctionAnalysis(const TargetMachine &tm);
explicit MachineFunctionAnalysis(const TargetMachine &tm,
MachineFunctionInitializer *MFInitializer);
~MachineFunctionAnalysis() override;

MachineFunction &getMF() const { return *MF; }
38 changes: 38 additions & 0 deletions llvm/include/llvm/CodeGen/MachineFunctionInitializer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===- MachineFunctionInitalizer.h - machine function initializer ---------===//
//
// 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() {}

/// Initialize the machine function.
///
/// Return true if error occurred.
virtual bool initializeMachineFunction(MachineFunction &MF) = 0;
};

} // end namespace llvm

#endif
20 changes: 20 additions & 0 deletions llvm/include/llvm/IR/DiagnosticInfo.h
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ class LLVMContextImpl;
class Twine;
class Value;
class DebugLoc;
class SMDiagnostic;

/// \brief Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity {
@@ -56,6 +57,7 @@ enum DiagnosticKind {
DK_OptimizationRemarkMissed,
DK_OptimizationRemarkAnalysis,
DK_OptimizationFailure,
DK_MIRParser,
DK_FirstPluginKind
};

@@ -386,6 +388,24 @@ class DiagnosticInfoOptimizationRemarkAnalysis
bool isEnabled() const override;
};

/// Diagnostic information for machine IR parser.
class DiagnosticInfoMIRParser : public DiagnosticInfo {
const SMDiagnostic &Diagnostic;

public:
DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
const SMDiagnostic &Diagnostic)
: DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}

const SMDiagnostic &getDiagnostic() const { return Diagnostic; }

void print(DiagnosticPrinter &DP) const override;

static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_MIRParser;
}
};

// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)

7 changes: 7 additions & 0 deletions llvm/include/llvm/IR/DiagnosticPrinter.h
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ namespace llvm {
// Forward declarations.
class Module;
class raw_ostream;
class SMDiagnostic;
class StringRef;
class Twine;
class Value;
@@ -51,6 +52,9 @@ class DiagnosticPrinter {
// IR related types.
virtual DiagnosticPrinter &operator<<(const Value &V) = 0;
virtual DiagnosticPrinter &operator<<(const Module &M) = 0;

// Other types.
virtual DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) = 0;
};

/// \brief Basic diagnostic printer that uses an underlying raw_ostream.
@@ -81,6 +85,9 @@ class DiagnosticPrinterRawOStream : public DiagnosticPrinter {
// IR related types.
DiagnosticPrinter &operator<<(const Value &V) override;
DiagnosticPrinter &operator<<(const Module &M) override;

// Other types.
DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) override;
};
} // End namespace llvm

4 changes: 2 additions & 2 deletions llvm/include/llvm/Support/SourceMgr.h
Original file line number Diff line number Diff line change
@@ -276,8 +276,8 @@ class SMDiagnostic {
return FixIts;
}

void print(const char *ProgName, raw_ostream &S,
bool ShowColors = true) const;
void print(const char *ProgName, raw_ostream &S, bool ShowColors = true,
bool ShowKindLabel = true) const;
};

} // end llvm namespace
20 changes: 11 additions & 9 deletions llvm/include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ namespace llvm {
class InstrItineraryData;
class GlobalValue;
class Mangler;
class MachineFunctionInitializer;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
@@ -210,11 +211,11 @@ class TargetMachine {
/// emitted. Typically this will involve several steps of code generation.
/// This method should return true if emission of this file type is not
/// supported, or false on success.
virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
CodeGenFileType,
bool /*DisableVerify*/ = true,
AnalysisID /*StartAfter*/ = nullptr,
AnalysisID /*StopAfter*/ = nullptr) {
virtual bool addPassesToEmitFile(
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr,
AnalysisID /*StopAfter*/ = nullptr,
MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
return true;
}

@@ -258,10 +259,11 @@ class LLVMTargetMachine : public TargetMachine {

/// Add passes to the specified pass manager to get the specified file
/// emitted. Typically this will involve several steps of code generation.
bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
CodeGenFileType FileType, bool DisableVerify = true,
AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr) override;
bool addPassesToEmitFile(
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify = true, AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr,
MachineFunctionInitializer *MFInitializer = 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
19 changes: 10 additions & 9 deletions llvm/lib/CodeGen/LLVMTargetMachine.cpp
Original file line number Diff line number Diff line change
@@ -87,11 +87,11 @@ TargetIRAnalysis LLVMTargetMachine::getTargetIRAnalysis() {
}

/// addPassesToX helper drives creation and initialization of TargetPassConfig.
static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
PassManagerBase &PM,
bool DisableVerify,
AnalysisID StartAfter,
AnalysisID StopAfter) {
static MCContext *
addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
bool DisableVerify, AnalysisID StartAfter,
AnalysisID StopAfter,
MachineFunctionInitializer *MFInitializer = nullptr) {

// Add internal analysis passes from the target machine.
PM.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
@@ -121,7 +121,7 @@ static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
PM.add(MMI);

// Set up a MachineFunction for the rest of CodeGen to work on.
PM.add(new MachineFunctionAnalysis(*TM));
PM.add(new MachineFunctionAnalysis(*TM, MFInitializer));

// Enable FastISel with -fast, but allow that to be overridden.
if (EnableFastISelOption == cl::BOU_TRUE ||
@@ -142,10 +142,11 @@ static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,

bool LLVMTargetMachine::addPassesToEmitFile(
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter,
MachineFunctionInitializer *MFInitializer) {
// Add common CodeGen passes.
MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
StartAfter, StopAfter);
MCContext *Context = addPassesToGenerateCode(
this, PM, DisableVerify, StartAfter, StopAfter, MFInitializer);
if (!Context)
return true;

Loading

0 comments on commit 735c47e

Please sign in to comment.