From cc041ba03aed685400197fb938b7a583713d25af Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Jan 2006 04:13:11 +0000 Subject: [PATCH] Initial checkin of the InlineAsm class git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25570 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/InlineAsm.h | 89 ++++++++++++++++++++++++++++++++++++++++ include/llvm/Module.h | 61 ++++++++++++++++++++------- include/llvm/Value.h | 3 +- lib/VMCore/AsmWriter.cpp | 12 +++++- lib/VMCore/Globals.cpp | 4 +- lib/VMCore/InlineAsm.cpp | 50 ++++++++++++++++++++++ lib/VMCore/Module.cpp | 19 ++++++++- 7 files changed, 217 insertions(+), 21 deletions(-) create mode 100644 include/llvm/InlineAsm.h create mode 100644 lib/VMCore/InlineAsm.cpp diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h new file mode 100644 index 00000000000..a35825d44a9 --- /dev/null +++ b/include/llvm/InlineAsm.h @@ -0,0 +1,89 @@ +//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class represents the inline asm strings, which are Value*'s that are +// used as the callee operand of call instructions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INLINEASM_H +#define LLVM_INLINEASM_H + +#include "llvm/Value.h" + +namespace llvm { + +class AssemblyAnnotationWriter; +class PointerType; +class FunctionType; +class Module; +template struct ilist_traits; +template class SymbolTableListTraits; + +class InlineAsm : public Value { + friend class SymbolTableListTraits >; + InlineAsm(const InlineAsm &); // do not implement + void operator=(const InlineAsm&); // do not implement + + void setParent(Module *Parent); + InlineAsm *Prev, *Next; + void setNext(InlineAsm *N) { Next = N; } + void setPrev(InlineAsm *N) { Prev = N; } + InlineAsm *getNext() { return Next; } + const InlineAsm *getNext() const { return Next; } + InlineAsm *getPrev() { return Prev; } + const InlineAsm *getPrev() const { return Prev; } + + Module *Parent; + std::string AsmString, Constraints; + bool AsmHasSideEffects; +public: + InlineAsm(const FunctionType *Ty, const std::string &AsmString, + const std::string &Constraints, bool hasSideEffects, + const std::string &Name = "", Module *ParentModule = 0); + + bool getHasSideEffects() const { return AsmHasSideEffects; } + void setSideEffects(bool X) { AsmHasSideEffects = X; } + + /// getType - InlineAsm's are always pointers. + /// + const PointerType *getType() const { + return reinterpret_cast(Value::getType()); + } + + /// getFunctionType - InlineAsm's are always pointers to functions. + /// + const FunctionType *getFunctionType() const; + + /// getParent - Get the module that this global value is contained inside + /// of... + Module *getParent() { return Parent; } + const Module *getParent() const { return Parent; } + + + /// removeFromParent/eraseFromParent - Unlink and unlink/delete this object + /// from the module it is embedded into. + void removeFromParent(); + void eraseFromParent(); + + virtual void print(std::ostream &O) const { print(O, 0); } + void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const InlineAsm *) { return true; } + static inline bool classof(const Value *V) { + return V->getValueType() == Value::InlineAsmVal; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Module.h b/include/llvm/Module.h index d8f6a455cc6..917fd429d9a 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -21,6 +21,7 @@ #include "llvm/Function.h" #include "llvm/GlobalVariable.h" +#include "llvm/InlineAsm.h" #include "llvm/ADT/SetVector.h" #include "llvm/Support/DataTypes.h" @@ -45,11 +46,19 @@ template<> struct ilist_traits static void destroySentinel(GlobalVariable *GV) { delete GV; } static iplist &getList(Module *M); }; +template<> struct ilist_traits +: public SymbolTableListTraits { + // createSentinel is used to create a node that marks the end of the list. + static InlineAsm *createSentinel(); + static void destroySentinel(InlineAsm *GV) { delete GV; } + static iplist &getList(Module *M); +}; class Module { public: typedef iplist GlobalListType; typedef iplist FunctionListType; + typedef iplist InlineAsmListType; typedef SetVector LibraryListType; // Global Variable iterators. @@ -60,6 +69,10 @@ public: typedef FunctionListType::iterator iterator; typedef FunctionListType::const_iterator const_iterator; + // Inline Asm iterators. + typedef InlineAsmListType::iterator inlineasm_iterator; + typedef InlineAsmListType::const_iterator const_inlineasm_iterator; + // Library list iterators. typedef LibraryListType::const_iterator lib_iterator; @@ -69,6 +82,7 @@ public: private: GlobalListType GlobalList; // The Global Variables in the module FunctionListType FunctionList; // The Functions in the module + InlineAsmListType InlineAsmList; // The inline asm objects in the module. LibraryListType LibraryList; // The Libraries needed by the module std::string GlobalScopeAsm; // Inline Asm at global scope. SymbolTable *SymTab; // Symbol Table for the module @@ -98,8 +112,8 @@ public: void setPointerSize(PointerSize PS) { PtrSize = PS; } // Access to any module-scope inline asm blocks. - const std::string &getInlineAsm() const { return GlobalScopeAsm; } - void setInlineAsm(const std::string &Asm) { GlobalScopeAsm = Asm; } + const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; } + void setModuleInlineAsm(const std::string &Asm) { GlobalScopeAsm = Asm; } //===--------------------------------------------------------------------===// // Methods for easy access to the functions in the module. @@ -174,17 +188,19 @@ public: // table. // - /// Get the underlying elements of the Module... - inline const GlobalListType &getGlobalList() const { return GlobalList; } - inline GlobalListType &getGlobalList() { return GlobalList; } - inline const FunctionListType &getFunctionList() const { return FunctionList;} - inline FunctionListType &getFunctionList() { return FunctionList;} + // Get the underlying elements of the Module. + const GlobalListType &getGlobalList() const { return GlobalList; } + GlobalListType &getGlobalList() { return GlobalList; } + const FunctionListType &getFunctionList() const { return FunctionList; } + FunctionListType &getFunctionList() { return FunctionList; } + const InlineAsmListType &getInlineAsmList() const { return InlineAsmList; } + InlineAsmListType &getInlineAsmList() { return InlineAsmList; } /// getSymbolTable() - Get access to the symbol table for the module, where /// global variables and functions are identified. /// - inline SymbolTable &getSymbolTable() { return *SymTab; } - inline const SymbolTable &getSymbolTable() const { return *SymTab; } + SymbolTable &getSymbolTable() { return *SymTab; } + const SymbolTable &getSymbolTable() const { return *SymTab; } //===--------------------------------------------------------------------===// @@ -198,14 +214,29 @@ public: bool global_empty() const { return GlobalList.empty(); } // FunctionList interface - inline iterator begin() { return FunctionList.begin(); } - inline const_iterator begin() const { return FunctionList.begin(); } - inline iterator end () { return FunctionList.end(); } - inline const_iterator end () const { return FunctionList.end(); } + iterator begin() { return FunctionList.begin(); } + const_iterator begin() const { return FunctionList.begin(); } + iterator end () { return FunctionList.end(); } + const_iterator end () const { return FunctionList.end(); } - inline size_t size() const { return FunctionList.size(); } - inline bool empty() const { return FunctionList.empty(); } + size_t size() const { return FunctionList.size(); } + bool empty() const { return FunctionList.empty(); } + // Inline Asm list interface + inlineasm_iterator inlineasm_begin() { + return InlineAsmList.begin(); + } + const_inlineasm_iterator inlineasm_begin() const { + return InlineAsmList.begin(); + } + inlineasm_iterator inlineasm_end() { + return InlineAsmList.end(); + } + const_inlineasm_iterator inlineasm_end() const { + return InlineAsmList.end(); + } + bool inlineasm_empty() const { return InlineAsmList.empty(); } + //===--------------------------------------------------------------------===// // List of dependent library access functions diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 80ff9c68476..f3fa75ffda7 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -155,6 +155,7 @@ public: ConstantStructVal, // This is an instance of ConstantStruct ConstantPackedVal, // This is an instance of ConstantPacked ConstantPointerNullVal, // This is an instance of ConstantPointerNull + InlineAsmVal, // This is an instance of InlineAsm InstructionVal, // This is an instance of Instruction // Markers: @@ -166,7 +167,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value * /*V*/) { + static inline bool classof(const Value *) { return true; // Values are always values. } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index d0b8478f24c..c6a3845a07f 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -775,9 +775,9 @@ void AssemblyWriter::printModule(const Module *M) { if (!M->getTargetTriple().empty()) Out << "target triple = \"" << M->getTargetTriple() << "\"\n"; - if (!M->getInlineAsm().empty()) { + if (!M->getModuleInlineAsm().empty()) { // Split the string into lines, to make it easier to read the .ll file. - std::string Asm = M->getInlineAsm(); + std::string Asm = M->getModuleInlineAsm(); size_t CurPos = 0; size_t NewLine = Asm.find_first_of('\n', CurPos); while (NewLine != std::string::npos) { @@ -1269,6 +1269,14 @@ void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const { W.write(this); } +void InlineAsm::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const { + SlotMachine SlotTable(getParent()); + AssemblyWriter W(o, SlotTable, getParent(), AAW); + + assert(0 && "Inline asm printing unimplemented!"); + //W.write(this); +} + void BasicBlock::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const { SlotMachine SlotTable(getParent()); AssemblyWriter W(o, SlotTable, diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index be6c6eb0537..3ea8265ebad 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -1,4 +1,4 @@ -//===-- Globals.cpp - Implement the Global object classes -----------------===// +//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" +#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" #include "llvm/Support/LeakDetector.h" diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp new file mode 100644 index 00000000000..1eed8941bea --- /dev/null +++ b/lib/VMCore/InlineAsm.cpp @@ -0,0 +1,50 @@ +//===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the InlineAsm class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/InlineAsm.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/Support/LeakDetector.h" +using namespace llvm; + +InlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString, + const std::string &constraints, bool hasSideEffects, + const std::string &name, Module *ParentModule) + : Value(PointerType::get(Ty), Value::InlineAsmVal, name), + Parent(0), AsmString(asmString), Constraints(constraints), + AsmHasSideEffects(hasSideEffects) { + LeakDetector::addGarbageObject(this); + + if (ParentModule) + ParentModule->getInlineAsmList().push_back(this); +} + +const FunctionType *InlineAsm::getFunctionType() const { + return cast(getType()->getElementType()); +} + +void InlineAsm::setParent(Module *parent) { + if (getParent()) + LeakDetector::addGarbageObject(this); + Parent = parent; + if (getParent()) + LeakDetector::removeGarbageObject(this); +} + +void InlineAsm::removeFromParent() { + getParent()->getInlineAsmList().remove(this); +} + +void InlineAsm::eraseFromParent() { + getParent()->getInlineAsmList().erase(this); +} diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index de63b4baa70..e9b28f9faf5 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -44,17 +44,30 @@ GlobalVariable *ilist_traits::createSentinel() { return Ret; } +InlineAsm *ilist_traits::createSentinel() { + InlineAsm *Ret = new InlineAsm(FunctionType::get(Type::VoidTy, + std::vector(), false), "", "", + false); + // This should not be garbage monitored. + LeakDetector::removeGarbageObject(Ret); + return Ret; +} + iplist &ilist_traits::getList(Module *M) { return M->getFunctionList(); } iplist &ilist_traits::getList(Module *M) { return M->getGlobalList(); } +iplist &ilist_traits::getList(Module *M) { + return M->getInlineAsmList(); +} // Explicit instantiations of SymbolTableListTraits since some of the methods -// are not in the public header file... +// are not in the public header file. template class SymbolTableListTraits; template class SymbolTableListTraits; +template class SymbolTableListTraits; //===----------------------------------------------------------------------===// // Primitive Module methods. @@ -66,6 +79,8 @@ Module::Module(const std::string &MID) FunctionList.setParent(this); GlobalList.setItemParent(this); GlobalList.setParent(this); + InlineAsmList.setItemParent(this); + InlineAsmList.setParent(this); SymTab = new SymbolTable(); } @@ -75,6 +90,8 @@ Module::~Module() { GlobalList.setParent(0); FunctionList.clear(); FunctionList.setParent(0); + InlineAsmList.clear(); + InlineAsmList.setParent(0); LibraryList.clear(); delete SymTab; }