diff options
author | Chris Lattner <sabre@nondot.org> | 2001-06-06 20:29:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-06-06 20:29:01 +0000 |
commit | 009505452b713ed2e3a8e99c5545a6e721c65495 (patch) | |
tree | 136a71c5b87bdf534d1f20a67558b49226b5a4d6 /include/llvm | |
parent | 8d0afd3d32d1d67f9aa5df250a1d6955aa8f1ac9 (diff) |
Initial revision
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
34 files changed, 3434 insertions, 0 deletions
diff --git a/include/llvm/Analysis/ModuleAnalyzer.h b/include/llvm/Analysis/ModuleAnalyzer.h new file mode 100644 index 0000000000..3abdd49afe --- /dev/null +++ b/include/llvm/Analysis/ModuleAnalyzer.h @@ -0,0 +1,113 @@ +//===-- llvm/Analysis/ModuleAnalyzer.h - Module analysis driver --*- C++ -*-==// +// +// This class provides a nice interface to traverse a module in a predictable +// way. This is used by the AssemblyWriter, BytecodeWriter, and SlotCalculator +// to do analysis of a module. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_MODULEANALYZER_H +#define LLVM_ANALYSIS_MODULEANALYZER_H + +#include "llvm/ConstantPool.h" +#include <set> + +class Module; +class Method; +class BasicBlock; +class Instruction; +class ConstPoolVal; +class MethodType; +class MethodArgument; + +class ModuleAnalyzer { + ModuleAnalyzer(const ModuleAnalyzer &); // do not impl + const ModuleAnalyzer &operator=(const ModuleAnalyzer &); // do not impl +public: + ModuleAnalyzer() {} + virtual ~ModuleAnalyzer() {} + +protected: + // processModule - Driver function to call all of my subclasses virtual + // methods. Commonly called by derived type's constructor. + // + bool processModule(const Module *M); + + //===--------------------------------------------------------------------===// + // Stages of processing Module level information + // + virtual bool processConstPool(const ConstantPool &CP, bool isMethod); + + // processType - This callback occurs when an derived type is discovered + // at the class level. This activity occurs when processing a constant pool. + // + virtual bool processType(const Type *Ty) { return false; } + + // processMethods - The default implementation of this method loops through + // all of the methods in the module and processModule's them. + // + virtual bool processMethods(const Module *M); + + //===--------------------------------------------------------------------===// + // Stages of processing a constant pool + // + + // processConstPoolPlane - Called once for every populated plane in the + // constant pool. The default action is to do nothing. The processConstPool + // method does the iteration over constants. + // + virtual bool processConstPoolPlane(const ConstantPool &CP, + const ConstantPool::PlaneType &Pl, + bool isMethod) { + return false; + } + + // processConstant is called once per each constant in the constant pool. It + // traverses the constant pool such that it visits each constant in the + // order of its type. Thus, all 'int' typed constants shall be visited + // sequentially, etc... + // + virtual bool processConstant(const ConstPoolVal *CPV) { return false; } + + // visitMethod - This member is called after the constant pool has been + // processed. The default implementation of this is a noop. + // + virtual bool visitMethod(const Method *M) { return false; } + + //===--------------------------------------------------------------------===// + // Stages of processing Method level information + // + // (processConstPool is also used above, with the isMethod flag set to true) + // + + // processMethod - Process all aspects of a method. + // + virtual bool processMethod(const Method *M); + + // processMethodArgument - This member is called for every argument that + // is passed into the method. + // + virtual bool processMethodArgument(const MethodArgument *MA) { return false; } + + // processBasicBlock - This member is called for each basic block in a methd. + // + virtual bool processBasicBlock(const BasicBlock *BB); + + //===--------------------------------------------------------------------===// + // Stages of processing BasicBlock level information + // + + // preProcessInstruction - This member is called for each Instruction in a + // method before processInstruction. + // + virtual bool preProcessInstruction(const Instruction *I); + + // processInstruction - This member is called for each Instruction in a method + // + virtual bool processInstruction(const Instruction *I) { return false; } + +private: + bool handleType(set<const Type *> &TypeSet, const Type *T); +}; + +#endif diff --git a/include/llvm/Analysis/SlotCalculator.h b/include/llvm/Analysis/SlotCalculator.h new file mode 100644 index 0000000000..99e40cbeb5 --- /dev/null +++ b/include/llvm/Analysis/SlotCalculator.h @@ -0,0 +1,96 @@ +//===-- llvm/Analysis/SlotCalculator.h - Calculate value slots ---*- C++ -*-==// +// +// This ModuleAnalyzer subclass calculates the slots that values will land in. +// This is useful for when writing bytecode or assembly out, because you have +// to know these things. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_SLOTCALCULATOR_H +#define LLVM_ANALYSIS_SLOTCALCULATOR_H + +#include "llvm/Analysis/ModuleAnalyzer.h" +#include "llvm/SymTabValue.h" +#include <vector> +#include <map> + +class SlotCalculator : public ModuleAnalyzer { + const Module *TheModule; + bool IgnoreNamedNodes; // Shall we not count named nodes? + + typedef vector<const Value*> TypePlane; + vector <TypePlane> Table; + map<const Value *, unsigned> NodeMap; + + // ModuleLevel - Used to keep track of which values belong to the module, + // and which values belong to the currently incorporated method. + // + vector <unsigned> ModuleLevel; + +public: + SlotCalculator(const Module *M, bool IgnoreNamed); + SlotCalculator(const Method *M, bool IgnoreNamed);// Start out in incorp state + inline ~SlotCalculator() {} + + // getValSlot returns < 0 on error! + int getValSlot(const Value *D) const; + + inline unsigned getNumPlanes() const { return Table.size(); } + inline unsigned getModuleLevel(unsigned Plane) const { + return Plane < ModuleLevel.size() ? ModuleLevel[Plane] : 0; + } + + inline const TypePlane &getPlane(unsigned Plane) const { + return Table[Plane]; + } + + // If you'd like to deal with a method, use these two methods to get its data + // into the SlotCalculator! + // + void incorporateMethod(const Method *M); + void purgeMethod(); + +protected: + // insertVal - Insert a value into the value table... + // + void insertVal(const Value *D); + + // visitMethod - This member is called after the constant pool has been + // processed. The default implementation of this is a noop. + // + virtual bool visitMethod(const Method *M); + + // processConstant is called once per each constant in the constant pool. It + // traverses the constant pool such that it visits each constant in the + // order of its type. Thus, all 'int' typed constants shall be visited + // sequentially, etc... + // + virtual bool processConstant(const ConstPoolVal *CPV); + + // processType - This callback occurs when an derived type is discovered + // at the class level. This activity occurs when processing a constant pool. + // + virtual bool processType(const Type *Ty); + + // processMethods - The default implementation of this method loops through + // all of the methods in the module and processModule's them. We don't want + // this (we want to explicitly visit them with incorporateMethod), so we + // disable it. + // + virtual bool processMethods(const Module *M) { return false; } + + // processMethodArgument - This member is called for every argument that + // is passed into the method. + // + virtual bool processMethodArgument(const MethodArgument *MA); + + // processBasicBlock - This member is called for each basic block in a methd. + // + virtual bool processBasicBlock(const BasicBlock *BB); + + // processInstruction - This member is called for each Instruction in a methd. + // + virtual bool processInstruction(const Instruction *I); +}; + +#endif diff --git a/include/llvm/Analysis/Verifier.h b/include/llvm/Analysis/Verifier.h new file mode 100644 index 0000000000..2feadca779 --- /dev/null +++ b/include/llvm/Analysis/Verifier.h @@ -0,0 +1,28 @@ +//===-- llvm/Analysis/Verifier.h - Module Verifier ---------------*- C++ -*-==// +// +// This file defines the method verifier interface, that can be used for some +// sanity checking of input to the system. +// +// Note that this does not provide full 'java style' security and verifications, +// instead it just tries to ensure that code is well formed. +// +// To see what specifically is checked, look at the top of Verifier.cpp +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_VERIFIER_H +#define LLVM_ANALYSIS_VERIFIER_H + +#include <vector> +#include <string> +class Module; +class Method; + +// verify - Check a module or method for validity. If errors are detected, +// error messages corresponding to the problem are added to the errorMsgs +// vectors, and a value of true is returned. +// +bool verify(const Module *M, vector<string> &ErrorMsgs); +bool verify(const Method *M, vector<string> &ErrorMsgs); + +#endif diff --git a/include/llvm/Assembly/Parser.h b/include/llvm/Assembly/Parser.h new file mode 100644 index 0000000000..5ac6ec20fa --- /dev/null +++ b/include/llvm/Assembly/Parser.h @@ -0,0 +1,66 @@ +//===-- llvm/assembly/Parser.h - Parser for VM assembly files ----*- C++ -*--=// +// +// These classes are implemented by the lib/AssemblyParser library. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ASSEMBLY_PARSER_H +#define LLVM_ASSEMBLY_PARSER_H + +#include <string> + +class Module; +class ToolCommandLine; +class ParseException; + + +// The useful interface defined by this file... Parse an ascii file, and return +// the internal representation in a nice slice'n'dice'able representation. +// +Module *ParseAssemblyFile(const ToolCommandLine &Opts) throw (ParseException); + +//===------------------------------------------------------------------------=== +// Helper Classes +//===------------------------------------------------------------------------=== + +// ParseException - For when an exceptional event is generated by the parser. +// This class lets you print out the exception message +// +class ParseException { +public: + ParseException(const ToolCommandLine &Opts, const string &message, + int LineNo = -1, int ColNo = -1); + + ParseException(const ParseException &E); + + // getMessage - Return the message passed in at construction time plus extra + // information extracted from the options used to parse with... + // + const string getMessage() const; + + inline const string getRawMessage() const { // Just the raw message... + return Message; + } + + inline const ToolCommandLine &getOptions() const { + return Opts; // Get the options obj used to parse. + } + + // getErrorLocation - Return the line and column number of the error in the + // input source file. The source filename can be derived from the + // ParserOptions in effect. If positional information is not applicable, + // these will return a value of -1. + // + inline const void getErrorLocation(int &Line, int &Column) const { + Line = LineNo; Column = ColumnNo; + } + +private : + const ToolCommandLine &Opts; + string Message; + int LineNo, ColumnNo; // -1 if not relevant + + ParseException &operator=(const ParseException &E); // objects by reference +}; + +#endif diff --git a/include/llvm/Assembly/Writer.h b/include/llvm/Assembly/Writer.h new file mode 100644 index 0000000000..71e2f4e054 --- /dev/null +++ b/include/llvm/Assembly/Writer.h @@ -0,0 +1,79 @@ +//===-- llvm/assembly/Writer.h - Printer for VM assembly files ---*- C++ -*--=// +// +// This functionality is implemented by the lib/AssemblyWriter library. +// This library is used to print VM assembly language files to an iostream. It +// can print VM code at a variety of granularities, ranging from a whole class +// down to an individual instruction. This makes it useful for debugging. +// +// This library uses the Analysis library to figure out offsets for +// variables in the method tables... +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ASSEMBLY_WRITER_H +#define LLVM_ASSEMBLY_WRITER_H + +#include <iostream> +#include "llvm/Type.h" + +class Module; +class Method; +class BasicBlock; +class Instruction; + +// The only interface defined by this file... convert the internal +// representation of an object into an ascii bytestream that the parser can +// understand later... (the parser only understands whole classes though) +// +void WriteToAssembly(const Module *Module, ostream &o); +void WriteToAssembly(const Method *Method, ostream &o); +void WriteToAssembly(const BasicBlock *BB, ostream &o); +void WriteToAssembly(const Instruction *In, ostream &o); +void WriteToAssembly(const ConstPoolVal *V, ostream &o); + + + +// Define operator<< to work on the various classes that we can send to an +// ostream... +// +inline ostream &operator<<(ostream &o, const Module *C) { + WriteToAssembly(C, o); return o; +} + +inline ostream &operator<<(ostream &o, const Method *M) { + WriteToAssembly(M, o); return o; +} + +inline ostream &operator<<(ostream &o, const BasicBlock *B) { + WriteToAssembly(B, o); return o; +} + +inline ostream &operator<<(ostream &o, const Instruction *I) { + WriteToAssembly(I, o); return o; +} + +inline ostream &operator<<(ostream &o, const ConstPoolVal *I) { + WriteToAssembly(I, o); return o; +} + + +inline ostream &operator<<(ostream &o, const Type *T) { + if (!T) return o << "<null Type>"; + return o << T->getName(); +} + +inline ostream &operator<<(ostream &o, const Value *I) { + switch (I->getValueType()) { + case Value::TypeVal: return o << (const Type*)I; + case Value::ConstantVal: WriteToAssembly((const ConstPoolVal*)I, o); break; + case Value::MethodArgumentVal: return o <<I->getType() << " " << I->getName(); + case Value::InstructionVal: WriteToAssembly((const Instruction *)I, o); break; + case Value::BasicBlockVal: WriteToAssembly((const BasicBlock *)I, o); break; + case Value::MethodVal: WriteToAssembly((const Method *)I, o); break; + case Value::ModuleVal: WriteToAssembly((const Module *)I, o); break; + default: return o << "<unknown value type: " << I->getValueType() << ">"; + } + return o; +} + +#endif diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h new file mode 100644 index 0000000000..6873ef2deb --- /dev/null +++ b/include/llvm/BasicBlock.h @@ -0,0 +1,246 @@ +//===-- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*--=// +// +// This file contains the declaration of the BasicBlock class, which represents +// a single basic block in the VM. +// +// Note that basic blocks themselves are Def's, because they are referenced +// by instructions like branches and can go in switch tables and stuff... +// +// This may see wierd at first, but it's really pretty cool. :) +// +//===----------------------------------------------------------------------===// +// +// Note that well formed basic blocks are formed of a list of instructions +// followed by a single TerminatorInst instruction. TerminatorInst's may not +// occur in the middle of basic blocks, and must terminate the blocks. +// +// This code allows malformed basic blocks to occur, because it may be useful +// in the intermediate stage of analysis or modification of a program. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BASICBLOCK_H +#define LLVM_BASICBLOCK_H + +#include "llvm/Value.h" // Get the definition of Value +#include "llvm/ValueHolder.h" +#include "llvm/InstrTypes.h" +#include <list> + +class Instruction; +class Method; +class BasicBlock; +class TerminatorInst; + +typedef UseTy<BasicBlock> BasicBlockUse; + +class BasicBlock : public Value { // Basic blocks are data objects also +public: + typedef ValueHolder<Instruction, BasicBlock> InstListType; +private : + InstListType InstList; + + friend class ValueHolder<BasicBlock,Method>; + void setParent(Method *parent); + +public: + BasicBlock(const string &Name = "", Method *Parent = 0); + ~BasicBlock(); + + // Specialize setName to take care of symbol table majik + virtual void setName(const string &name); + + const Method *getParent() const { return (const Method*)InstList.getParent();} + Method *getParent() { return (Method*)InstList.getParent(); } + + const InstListType &getInstList() const { return InstList; } + InstListType &getInstList() { return InstList; } + + // getTerminator() - If this is a well formed basic block, then this returns + // a pointer to the terminator instruction. If it is not, then you get a null + // pointer back. + // + TerminatorInst *getTerminator(); + const TerminatorInst *const getTerminator() const; + + // hasConstantPoolReferences() - This predicate is true if there is a + // reference to this basic block in the constant pool for this method. For + // example, if a block is reached through a switch table, that table resides + // in the constant pool, and the basic block is reference from it. + // + bool hasConstantPoolReferences() const; + + // dropAllReferences() - This function causes all the subinstructions to "let + // go" of all references that they are maintaining. This allows one to + // 'delete' a whole class at a time, even though there may be circular + // references... first all references are dropped, and all use counts go to + // zero. Then everything is delete'd for real. Note that no operations are + // valid on an object that has "dropped all references", except operator + // delete. + // + void dropAllReferences(); + + // splitBasicBlock - This splits a basic block into two at the specified + // instruction. Note that all instructions BEFORE the specified iterator stay + // as part of the original basic block, an unconditional branch is added to + // the new BB, and the rest of the instructions in the BB are moved to the new + // BB, including the old terminator. The newly formed BasicBlock is returned. + // This function invalidates the specified iterator. + // + // Note that this only works on well formed basic blocks (must have a + // terminator), and 'I' must not be the end of instruction list (which would + // cause a degenerate basic block to be formed, having a terminator inside of + // the basic block). + // + BasicBlock *splitBasicBlock(InstListType::iterator I); + + //===--------------------------------------------------------------------===// + // Predecessor iterator code + //===--------------------------------------------------------------------===// + // + // This is used to figure out what basic blocks we could be coming from. + // + + // Forward declare iterator class template... + template <class _Ptr, class _USE_iterator> class PredIterator; + + typedef PredIterator<BasicBlock*, use_iterator> pred_iterator; + typedef PredIterator<const BasicBlock*, + use_const_iterator> pred_const_iterator; + + inline pred_iterator pred_begin() ; + inline pred_const_iterator pred_begin() const; + inline pred_iterator pred_end() ; + inline pred_const_iterator pred_end() const; + + //===--------------------------------------------------------------------===// + // Successor iterator code + //===--------------------------------------------------------------------===// + // + // This is used to figure out what basic blocks we could be going to... + // + + // Forward declare iterator class template... + template <class _Term, class _BB> class SuccIterator; + + typedef SuccIterator<TerminatorInst*, BasicBlock*> succ_iterator; + typedef SuccIterator<const TerminatorInst*, + const BasicBlock*> succ_const_iterator; + + inline succ_iterator succ_begin() ; + inline succ_const_iterator succ_begin() const; + inline succ_iterator succ_end() ; + inline succ_const_iterator succ_end() const; + + //===--------------------------------------------------------------------===// + // END of interesting code... + //===--------------------------------------------------------------------===// + // + // Thank god C++ compilers are good at stomping out tons of templated code... + // + template <class _Ptr, class _USE_iterator> // Predecessor Iterator + class PredIterator { + const _Ptr ThisBB; + _USE_iterator It; + public: + typedef PredIterator<_Ptr,_USE_iterator> _Self; + + typedef bidirectional_iterator_tag iterator_category; + typedef _Ptr pointer; + + inline PredIterator(_Ptr BB) : ThisBB(BB), It(BB->use_begin()) {} + inline PredIterator(_Ptr BB, bool) : ThisBB(BB), It(BB->use_end()) {} + + inline bool operator==(const _Self& x) const { return It == x.It; } + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + inline pointer operator*() const { + assert ((*It)->getValueType() == Value::InstructionVal); + return ((Instruction *)(*It))->getParent(); + } + inline pointer *operator->() const { return &(operator*()); } + + inline _Self& operator++() { // Preincrement + do { // Loop to ignore constant pool references + ++It; + } while (It != ThisBB->use_end() && + ((*It)->getValueType() != Value::ConstantVal)); + + // DOES THIS WORK??? + //((*It)->getValueType() != Value::BasicBlockVal)); + return *this; + } + + inline _Self operator++(int) { // Postincrement + _Self tmp = *this; ++*this; return tmp; + } + + inline _Self& operator--() { --It; return *this; } // Predecrement + inline _Self operator--(int) { // Postdecrement + _Self tmp = *this; --*this; return tmp; + } + }; + + template <class _Term, class _BB> // Successor Iterator + class SuccIterator { + const _Term Term; + unsigned idx; + public: + typedef SuccIterator<_Term, _BB> _Self; + typedef forward_iterator_tag iterator_category; + typedef _BB pointer; + + inline SuccIterator(_Term T) : Term(T), idx(0) {} // begin iterator + inline SuccIterator(_Term T, bool) + : Term(T), idx(Term->getNumSuccessors()) {} // end iterator + + inline bool operator==(const _Self& x) const { return idx == x.idx; } + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + inline pointer operator*() const { return Term->getSuccessor(idx); } + inline pointer *operator->() const { return &(operator*()); } + + inline _Self& operator++() { ++idx; return *this; } // Preincrement + inline _Self operator++(int) { // Postincrement + _Self tmp = *this; ++*this; return tmp; + } + + inline _Self& operator--() { --idx; return *this; } // Predecrement + inline _Self operator--(int) { // Postdecrement + _Self tmp = *this; --*this; return tmp; + } + }; +}; + + +//===--------------------------------------------------------------------===// +// Implement some stuff prototyped above... +//===--------------------------------------------------------------------===// + +inline BasicBlock::pred_iterator BasicBlock::pred_begin() { + return pred_iterator(this); +} +inline BasicBlock::pred_const_iterator BasicBlock::pred_begin() const { + return pred_const_iterator(this); +} +inline BasicBlock::pred_iterator BasicBlock::pred_end() { + return pred_iterator(this,true); +} +inline BasicBlock::pred_const_iterator BasicBlock::pred_end() const { + return pred_const_iterator(this,true); +} + +inline BasicBlock::succ_iterator BasicBlock::succ_begin() { + return succ_iterator(getTerminator()); +} +inline BasicBlock::succ_const_iterator BasicBlock::succ_begin() const { + return succ_const_iterator(getTerminator()); +} +inline BasicBlock::succ_iterator BasicBlock::succ_end() { + return succ_iterator(getTerminator(),true); +} +inline BasicBlock::succ_const_iterator BasicBlock::succ_end() const { + return succ_const_iterator(getTerminator(),true); +} + +#endif diff --git a/include/llvm/Bytecode/Format.h b/include/llvm/Bytecode/Format.h new file mode 100644 index 0000000000..a87f8d18a6 --- /dev/null +++ b/include/llvm/Bytecode/Format.h @@ -0,0 +1,33 @@ +//===-- llvm/Bytecode/Format.h - VM bytecode file format info ----*- C++ -*--=// +// +// This header defines intrinsic constants that are useful to libraries that +// need to hack on bytecode files directly, like the reader and writer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BYTECODE_FORMAT_H +#define LLVM_BYTECODE_FORMAT_H + +class BytecodeFormat { // Throw the constants into a poorman's namespace... + BytecodeFormat(); // do not implement +public: + + // ID Numbers that are used in bytecode files... + enum FileBlockIDs { + // File level identifiers... + Module = 0x01, + + // Module subtypes: + Method = 0x11, + ConstantPool, + SymbolTable, + ModuleGlobalInfo, + + // Method subtypes: + MethodInfo = 0x21, + // Can also have ConstantPool block + // Can also have SymbolTable block + BasicBlock = 0x31, // May contain many basic blocks + }; +}; +#endif diff --git a/include/llvm/Bytecode/Primitives.h b/include/llvm/Bytecode/Primitives.h new file mode 100644 index 0000000000..f4b232b368 --- /dev/null +++ b/include/llvm/Bytecode/Primitives.h @@ -0,0 +1,237 @@ +//===-- llvm/Bytecode/Primitives.h - Bytecode file format prims --*- C++ -*--=// +// +// This header defines some basic functions for reading and writing basic +// primitive types to a bytecode stream. +// +// Using the routines defined in this file does not require linking to any +// libraries, as all of the services are small self contained units that are to +// be inlined as neccesary. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BYTECODE_PRIMITIVES_H +#define LLVM_BYTECODE_PRIMITIVES_H + +#include "llvm/Tools/DataTypes.h" +#include <string> +#include <vector> + +//===----------------------------------------------------------------------===// +// Reading Primitives +//===----------------------------------------------------------------------===// + +static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, + unsigned &Result) { + if (Buf+4 > EndBuf) return true; +#ifdef LITTLE_ENDIAN + Result = *(unsigned*)Buf; +#else + Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24); +#endif + Buf += 4; + return false; |