From d0fef32e5f3700c7de6dfc50a1a3815659b7d19e Mon Sep 17 00:00:00 2001 From: Daniel Malea Date: Wed, 8 May 2013 20:38:31 +0000 Subject: [PATCH] Pull up AssemblyWriter interface into header to allow subclassing - made all functions virtual so that subclasses can specialize them - add printInstructionLine so that subclasses can choose whether or not to print the newline character (without having to implement printBasicBlock() - added a second constructor to AssemblyWriter that does not require a SlotTracker, as required in order to keep the SlotTracker helper class outside AsmWriter.h and buried in the implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181466 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/AsmWriter.h | 118 +++++++++++++++++++++++++++++++++ lib/IR/AsmWriter.cpp | 126 ++++++++++++------------------------ 2 files changed, 160 insertions(+), 84 deletions(-) create mode 100644 include/llvm/IR/AsmWriter.h diff --git a/include/llvm/IR/AsmWriter.h b/include/llvm/IR/AsmWriter.h new file mode 100644 index 00000000000..aac7975ee68 --- /dev/null +++ b/include/llvm/IR/AsmWriter.h @@ -0,0 +1,118 @@ +//===-- llvm/IR/AsmWriter.h - Printing LLVM IR as an assembly file - C++ --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files defines the interface for the AssemblyWriter class used to print +// LLVM IR and various helper classes that are used in printing. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_ASSEMBLYWRITER_H +#define LLVM_IR_ASSEMBLYWRITER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/Support/FormattedStream.h" + +namespace llvm { + +class BasicBlock; +class Function; +class GlobalValue; +class Module; +class NamedMDNode; +class Value; +class SlotTracker; + +/// Create a new SlotTracker for a Module +SlotTracker *createSlotTracker(const Module *M); + +//===----------------------------------------------------------------------===// +// TypePrinting Class: Type printing machinery +//===----------------------------------------------------------------------===// + +class TypePrinting { + TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION; + void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION; +public: + + /// NamedTypes - The named types that are used by the current module. + TypeFinder NamedTypes; + + /// NumberedTypes - The numbered types, along with their value. + DenseMap NumberedTypes; + + + TypePrinting() {} + ~TypePrinting() {} + + void incorporateTypes(const Module &M); + + void print(Type *Ty, raw_ostream &OS); + + void printStructBody(StructType *Ty, raw_ostream &OS); +}; + +class AssemblyWriter { +protected: + formatted_raw_ostream &Out; + const Module *TheModule; + +private: + OwningPtr ModuleSlotTracker; + SlotTracker &Machine; + TypePrinting TypePrinter; + AssemblyAnnotationWriter *AnnotationWriter; + +public: + /// Construct an AssemblyWriter with an external SlotTracker + AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, AssemblyAnnotationWriter *AAW); + + /// Construct an AssemblyWriter with an internally allocated SlotTracker + AssemblyWriter(formatted_raw_ostream &o, const Module *M, + AssemblyAnnotationWriter *AAW); + + virtual ~AssemblyWriter(); + + virtual void printMDNodeBody(const MDNode *MD); + virtual void printNamedMDNode(const NamedMDNode *NMD); + + virtual void printModule(const Module *M); + + virtual void writeOperand(const Value *Op, bool PrintType); + virtual void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx); + virtual void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); + + virtual void writeAllMDNodes(); + virtual void writeMDNode(unsigned Slot, const MDNode *Node); + virtual void writeAllAttributeGroups(); + + virtual void printTypeIdentities(); + virtual void printGlobal(const GlobalVariable *GV); + virtual void printAlias(const GlobalAlias *GV); + virtual void printFunction(const Function *F); + virtual void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx); + virtual void printBasicBlock(const BasicBlock *BB); + virtual void printInstructionLine(const Instruction &I); + virtual void printInstruction(const Instruction &I); + +private: + void init(); + + // printInfoComment - Print a little comment after the instruction indicating + // which slot it occupies. + void printInfoComment(const Value &V); +}; + +} // namespace llvm + +#endif //LLVM_IR_ASMWRITER_H diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 7761127d557..c94620372a2 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -22,6 +22,7 @@ #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/DebugInfo.h" +#include "llvm/IR/AsmWriter.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" @@ -153,35 +154,8 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { isa(V) ? GlobalPrefix : LocalPrefix); } -//===----------------------------------------------------------------------===// -// TypePrinting Class: Type printing machinery -//===----------------------------------------------------------------------===// - -/// TypePrinting - Type printing machinery. -namespace { -class TypePrinting { - TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION; - void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION; -public: - - /// NamedTypes - The named types that are used by the current module. - TypeFinder NamedTypes; - - /// NumberedTypes - The numbered types, along with their value. - DenseMap NumberedTypes; - - - TypePrinting() {} - ~TypePrinting() {} - - void incorporateTypes(const Module &M); - - void print(Type *Ty, raw_ostream &OS); - - void printStructBody(StructType *Ty, raw_ostream &OS); -}; -} // end anonymous namespace. +namespace llvm { void TypePrinting::incorporateTypes(const Module &M) { NamedTypes.run(M, false); @@ -313,14 +287,9 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { OS << '>'; } - - //===----------------------------------------------------------------------===// // SlotTracker Class: Enumerate slot numbers for unnamed values //===----------------------------------------------------------------------===// - -namespace { - /// This class provides computation of slot numbers for LLVM Assembly writing. /// class SlotTracker { @@ -418,8 +387,9 @@ private: void operator=(const SlotTracker &) LLVM_DELETED_FUNCTION; }; -} // end anonymous namespace - +SlotTracker *createSlotTracker(const Module *M) { + return new SlotTracker(M); +} static SlotTracker *createSlotTracker(const Value *V) { if (const Argument *FA = dyn_cast(V)) @@ -1200,8 +1170,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << ""; } -void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, - bool PrintType, const Module *Context) { +void WriteAsOperand(raw_ostream &Out, const Value *V, + bool PrintType, const Module *Context) { // Fast path: Don't construct and populate a TypePrinting object if we // won't be needing any types printed. @@ -1225,50 +1195,27 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context); } -namespace { +void AssemblyWriter::init() { + if (TheModule) + TypePrinter.incorporateTypes(*TheModule); +} -class AssemblyWriter { - formatted_raw_ostream &Out; - SlotTracker &Machine; - const Module *TheModule; - TypePrinting TypePrinter; - AssemblyAnnotationWriter *AnnotationWriter; -public: - inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, - const Module *M, - AssemblyAnnotationWriter *AAW) - : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { - if (M) - TypePrinter.incorporateTypes(*M); - } +AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, + AssemblyAnnotationWriter *AAW) + : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW) { + init(); +} - void printMDNodeBody(const MDNode *MD); - void printNamedMDNode(const NamedMDNode *NMD); +AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M, + AssemblyAnnotationWriter *AAW) + : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)), + Machine(*ModuleSlotTracker), AnnotationWriter(AAW) { + init(); +} - void printModule(const Module *M); - - void writeOperand(const Value *Op, bool PrintType); - void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx); - void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); - - void writeAllMDNodes(); - void writeAllAttributeGroups(); - - void printTypeIdentities(); - void printGlobal(const GlobalVariable *GV); - void printAlias(const GlobalAlias *GV); - void printFunction(const Function *F); - void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx); - void printBasicBlock(const BasicBlock *BB); - void printInstruction(const Instruction &I); - -private: - // printInfoComment - Print a little comment after the instruction indicating - // which slot it occupies. - void printInfoComment(const Value &V); -}; -} // end of anonymous namespace +AssemblyWriter::~AssemblyWriter() { } void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { if (Operand == 0) { @@ -1772,13 +1719,18 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { // Output all of the instructions in the basic block... for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - printInstruction(*I); - Out << '\n'; + printInstructionLine(*I); } if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } +/// printInstructionLine - Print an instruction and a newline character. +void AssemblyWriter::printInstructionLine(const Instruction &I) { + printInstruction(I); + Out << '\n'; +} + /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// @@ -2093,9 +2045,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { unsigned Kind = InstMD[i].first; if (Kind < MDNames.size()) { Out << ", !" << MDNames[Kind]; - } else { - Out << ", !"; - } + } else { + Out << ", !"; + } Out << ' '; WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine, TheModule); @@ -2127,6 +2079,11 @@ static void WriteMDNodeComment(const MDNode *Node, } } +void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) { + Out << '!' << Slot << " = metadata "; + printMDNodeBody(Node); +} + void AssemblyWriter::writeAllMDNodes() { SmallVector Nodes; Nodes.resize(Machine.mdn_size()); @@ -2135,8 +2092,7 @@ void AssemblyWriter::writeAllMDNodes() { Nodes[I->second] = cast(I->first); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { - Out << '!' << i << " = metadata "; - printMDNodeBody(Nodes[i]); + writeMDNode(i, Nodes[i]); } } @@ -2160,6 +2116,8 @@ void AssemblyWriter::writeAllAttributeGroups() { << I->first.getAsString(AttributeSet::FunctionIndex, true) << " }\n"; } +} // namespace llvm + //===----------------------------------------------------------------------===// // External Interface declarations //===----------------------------------------------------------------------===//