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) | |
download | external_llvm-009505452b713ed2e3a8e99c5545a6e721c65495.zip external_llvm-009505452b713ed2e3a8e99c5545a6e721c65495.tar.gz external_llvm-009505452b713ed2e3a8e99c5545a6e721c65495.tar.bz2 |
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 0000000..3abdd49 --- /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 0000000..99e40cb --- /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 0000000..2feadca --- /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 0000000..5ac6ec2 --- /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 0000000..71e2f4e --- /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 0000000..6873ef2 --- /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 0000000..a87f8d1 --- /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 0000000..f4b232b --- /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; +} + +static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, + uint64_t &Result) { + if (Buf+8 > EndBuf) return true; + +#ifdef LITTLE_ENDIAN + Result = *(uint64_t*)Buf; +#else + Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24) | + ((uint64_t)(Buf[4] | (Buf[5] << 8) | (Buf[6] << 16) | (Buf[7] << 24)) <<32); +#endif + Buf += 8; + return false; +} + +static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, + int &Result) { + return read(Buf, EndBuf, (unsigned &)Result); +} + +static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, + int64_t &Result) { + return read(Buf, EndBuf, (uint64_t &)Result); +} + + +// read_vbr - Read an unsigned integer encoded in variable bitrate format. +// +static inline bool read_vbr(const unsigned char *&Buf, + const unsigned char *EndBuf, unsigned &Result) { + unsigned Shift = Result = 0; + + do { + Result |= (unsigned)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80 && Buf < EndBuf); + + return Buf > EndBuf; +} + +static inline bool read_vbr(const unsigned char *&Buf, + const unsigned char *EndBuf, uint64_t &Result) { + unsigned Shift = 0; Result = 0; + + do { + Result |= (uint64_t)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80 && Buf < EndBuf); + return Buf > EndBuf; +} + +// read_vbr (signed) - Read a signed number stored in sign-magnitude format +static inline bool read_vbr(const unsigned char *&Buf, + const unsigned char *EndBuf, int &Result) { + unsigned R; + if (read_vbr(Buf, EndBuf, R)) return true; + if (R & 1) + Result = -(int)(R >> 1); + else + Result = (int)(R >> 1); + + return false; +} + + +static inline bool read_vbr(const unsigned char *&Buf, + const unsigned char *EndBuf, int64_t &Result) { + uint64_t R; + if (read_vbr(Buf, EndBuf, R)) return true; + if (R & 1) + Result = -(int64_t)(R >> 1); + else + Result = (int64_t)(R >> 1); + + return false; +} + +// align32 - Round up to multiple of 32 bits... +static inline bool align32(const unsigned char *&Buf, + const unsigned char *EndBuf) { + Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL)); + return Buf > EndBuf; +} + +static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, + string &Result, bool Aligned = true) { + unsigned Size; + if (read_vbr(Buf, EndBuf, Size)) return true; // Failure reading size? + if (Buf+Size > EndBuf) return true; // Size invalid? + + Result = string((char*)Buf, Size); + Buf += Size; + + if (Aligned) // If we should stay aligned do so... + if (align32(Buf, EndBuf)) return true; // Failure aligning? + + return false; +} + + +//===----------------------------------------------------------------------===// +// Writing Primitives +//===----------------------------------------------------------------------===// + +// output - If a position is specified, it must be in the valid portion of the +// string... note that this should be inlined always so only the relevant IF +// body should be included... +// +static inline void output(unsigned i, vector<unsigned char> &Out, int pos = -1){ +#ifdef LITTLE_ENDIAN + if (pos == -1) + Out.insert(Out.end(), (unsigned char*)&i, (unsigned char*)&i+4); + else + *(unsigned*)&Out[pos] = i; +#else + if (pos == -1) { // Be endian clean, little endian is our friend + Out.push_back((unsigned char)i); + Out.push_back((unsigned char)(i >> 8)); + Out.push_back((unsigned char)(i >> 16)); + Out.push_back((unsigned char)(i >> 24)); + } else { + Out[pos ] = (unsigned char)i; + Out[pos+1] = (unsigned char)(i >> 8); + Out[pos+2] = (unsigned char)(i >> 16); + Out[pos+3] = (unsigned char)(i >> 24); + } +#endif +} + +static inline void output(int i, vector<unsigned char> &Out) { + output((unsigned)i, Out); +} + +// output_vbr - Output an unsigned value, by using the least number of bytes +// possible. This is useful because many of our "infinite" values are really +// very small most of the time... but can be large a few times... +// +// Data format used: If you read a byte with the night bit set, use the low +// seven bits as data and then read another byte... +// +// Note that using this may cause the output buffer to become unaligned... +// +static inline void output_vbr(uint64_t i, vector<unsigned char> &out) { + while (1) { + if (i < 0x80) { // done? + out.push_back((unsigned char)i); // We know the high bit is clear... + return; + } + + // Nope, we are bigger than a character, output the next 7 bits and set the + // high bit to say that there is more coming... + out.push_back(0x80 | (i & 0x7F)); + i >>= 7; // Shift out 7 bits now... + } +} + +static inline void output_vbr(unsigned i, vector<unsigned char> &out) { + while (1) { + if (i < 0x80) { // done? + out.push_back((unsigned char)i); // We know the high bit is clear... + return; + } + + // Nope, we are bigger than a character, output the next 7 bits and set the + // high bit to say that there is more coming... + out.push_back(0x80 | (i & 0x7F)); + i >>= 7; // Shift out 7 bits now... + } +} + +static inline void output_vbr(int64_t i, vector<unsigned char> &out) { + if (i < 0) + output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit... + else + output_vbr((uint64_t)i << 1, out); // Low order bit is clear. +} + + +static inline void output_vbr(int i, vector<unsigned char> &out) { + if (i < 0) + output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit... + else + output_vbr((unsigned)i << 1, out); // Low order bit is clear. +} + +// align32 - emit the minimal number of bytes that will bring us to 32 bit +// alignment... +// +static inline void align32(vector<unsigned char> &Out) { + int NumPads = (4-(Out.size() & 3)) & 3; // Bytes to get padding to 32 bits + while (NumPads--) Out.push_back((unsigned char)0xAB); +} + +static inline void output(const string &s, vector<unsigned char> &Out, + bool Aligned = true) { + unsigned Len = s.length(); + output_vbr(Len, Out); // Strings may have an arbitrary length... + Out.insert(Out.end(), s.begin(), s.end()); + + if (Aligned) + align32(Out); // Make sure we are now aligned... +} + +#endif diff --git a/include/llvm/Bytecode/Reader.h b/include/llvm/Bytecode/Reader.h new file mode 100644 index 0000000..17ddfc8 --- /dev/null +++ b/include/llvm/Bytecode/Reader.h @@ -0,0 +1,24 @@ +//===-- llvm/Bytecode/Reader.h - Reader for VM bytecode files ----*- C++ -*--=// +// +// This functionality is implemented by the lib/BytecodeReader library. +// This library is used to read VM bytecode files from an iostream. +// +// Note that performance of this library is _crucial_ for performance of the +// JIT type applications, so we have designed the bytecode format to support +// quick reading. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BYTECODE_READER_H +#define LLVM_BYTECODE_READER_H + +#include <string> + +class Module; + +// Parse and return a class... +// +Module *ParseBytecodeFile(const string &Filename); +Module *ParseBytecodeBuffer(const char *Buffer, unsigned BufferSize); + +#endif diff --git a/include/llvm/Bytecode/Writer.h b/include/llvm/Bytecode/Writer.h new file mode 100644 index 0000000..e28ea77 --- /dev/null +++ b/include/llvm/Bytecode/Writer.h @@ -0,0 +1,25 @@ +//===-- llvm/Bytecode/Writer.h - Writer for VM bytecode files ----*- C++ -*--=// +// +// This functionality is implemented by the lib/BytecodeWriter library. +// This library is used to write VM bytecode files to an iostream. First, you +// have to make a BytecodeStream object, which you can then put a class into +// by using operator <<. +// +// This library uses the Analysis library to figure out offsets for +// variables in the method tables... +// +// Note that performance of this library is not as crucial as performance of the +// bytecode reader (which is to be used in JIT type applications), so we have +// designed the bytecode format to support quick reading. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BYTECODE_WRITER_H +#define LLVM_BYTECODE_WRITER_H + +#include <iostream.h> + +class Module; +void WriteBytecodeToFile(const Module *C, ostream &Out); + +#endif diff --git a/include/llvm/ConstPoolVals.h b/include/llvm/ConstPoolVals.h new file mode 100644 index 0000000..dbdda62 --- /dev/null +++ b/include/llvm/ConstPoolVals.h @@ -0,0 +1,234 @@ +//===-- llvm/ConstPoolVals.h - Constant Value nodes --------------*- C++ -*--=// +// +// This file contains the declarations for the ConstPoolVal class and all of +// its subclasses, which represent the different type of constant pool values +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CONSTPOOLVALS_H +#define LLVM_CONSTPOOLVALS_H + +#include "llvm/User.h" +#include "llvm/SymTabValue.h" +#include "llvm/Tools/DataTypes.h" +#include <vector> + +class ArrayType; +class StructType; + +//===----------------------------------------------------------------------===// +// ConstPoolVal Class +//===----------------------------------------------------------------------===// + +class ConstPoolVal; +typedef UseTy<ConstPoolVal> ConstPoolUse; + +class ConstPoolVal : public User { + SymTabValue *Parent; + + friend class ValueHolder<ConstPoolVal, SymTabValue>; + inline void setParent(SymTabValue *parent) { + Parent = parent; + } + +public: + inline ConstPoolVal(const Type *Ty, const string &Name = "") + : User(Ty, Value::ConstantVal, Name) { Parent = 0; } + + // Specialize setName to handle symbol table majik... + virtual void setName(const string &name); + + // Static constructor to create a '0' constant of arbitrary type... + static ConstPoolVal *getNullConstant(const Type *Ty); + + // clone() - Create a copy of 'this' value that is identical in all ways + // except the following: + // * The value has no parent + // * The value has no name + // + virtual ConstPoolVal *clone() const = 0; + + virtual string getStrValue() const = 0; + virtual bool equals(const ConstPoolVal *V) const = 0; + + inline const SymTabValue *getParent() const { return Parent; } + inline SymTabValue *getParent() { return Parent; } + + // if i > the number of operands, then getOperand() returns 0, and setOperand + // returns false. setOperand() may also return false if the operand is of + // the wrong type. + // + // Note that some subclasses may change this default no argument behavior + // + virtual Value *getOperand(unsigned i) { return 0; } + virtual const Value *getOperand(unsigned i) const { return 0; } + virtual bool setOperand(unsigned i, Value *Val) { return false; } + virtual void dropAllReferences() {} +}; + + + +//===----------------------------------------------------------------------===// +// Classes to represent constant pool variable defs +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +// ConstPoolBool - Boolean Values +// +class ConstPoolBool : public ConstPoolVal { + bool Val; + ConstPoolBool(const ConstPoolBool &CP); +public: + ConstPoolBool(bool V, const string &Name = ""); + + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + virtual ConstPoolVal *clone() const { return new ConstPoolBool(*this); } + + inline bool getValue() const { return Val; } + + // setValue - Be careful... if there is more than one 'use' of this node, then + // they will ALL see the value that you set... + // + inline void setValue(bool v) { Val = v; } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolSInt - Signed Integer Values [sbyte, short, int, long] +// +class ConstPoolSInt : public ConstPoolVal { + int64_t Val; + ConstPoolSInt(const ConstPoolSInt &CP); +public: + ConstPoolSInt(const Type *Ty, int64_t V, const string &Name = ""); + + virtual ConstPoolVal *clone() const { return new ConstPoolSInt(*this); } + + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + static bool isValueValidForType(const Type *Ty, int64_t V); + inline int64_t getValue() const { return Val; } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolUInt - Unsigned Integer Values [ubyte, ushort, uint, ulong] +// +class ConstPoolUInt : public ConstPoolVal { + uint64_t Val; + ConstPoolUInt(const ConstPoolUInt &CP); +public: + ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name = ""); + + virtual ConstPoolVal *clone() const { return new ConstPoolUInt(*this); } + + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + static bool isValueValidForType(const Type *Ty, uint64_t V); + inline uint64_t getValue() const { return Val; } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolFP - Floating Point Values [float, double] +// +class ConstPoolFP : public ConstPoolVal { + double Val; + ConstPoolFP(const ConstPoolFP &CP); +public: + ConstPoolFP(const Type *Ty, double V, const string &Name = ""); + + virtual ConstPoolVal *clone() const { return new ConstPoolFP(*this); } + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + static bool isValueValidForType(const Type *Ty, double V); + inline double getValue() const { return Val; } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolType - Type Declarations +// +class ConstPoolType : public ConstPoolVal { + const Type *Val; + ConstPoolType(const ConstPoolType &CPT); +public: + ConstPoolType(const Type *V, const string &Name = ""); + + virtual ConstPoolVal *clone() const { return new ConstPoolType(*this); } + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + inline const Type *getValue() const { return Val; } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolArray - Constant Array Declarations +// +class ConstPoolArray : public ConstPoolVal { + vector<ConstPoolUse> Val; + ConstPoolArray(const ConstPoolArray &CPT); +public: + ConstPoolArray(const ArrayType *T, vector<ConstPoolVal*> &V, + const string &Name = ""); + inline ~ConstPoolArray() { dropAllReferences(); } + + virtual ConstPoolVal *clone() const { return new ConstPoolArray(*this); } + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + inline const vector<ConstPoolUse> &getValues() const { return Val; } + + // Implement User stuff... + // + virtual Value *getOperand(unsigned i) { + return (i < Val.size()) ? Val[i] : 0; + } + virtual const Value *getOperand(unsigned i) const { + return (i < Val.size()) ? Val[i] : 0; + } + + // setOperand fails! You can't change a constant! + virtual bool setOperand(unsigned i, Value *Val) { return false; } + virtual void dropAllReferences() { Val.clear(); } +}; + + +//===--------------------------------------------------------------------------- +// ConstPoolStruct - Constant Struct Declarations +// +class ConstPoolStruct : public ConstPoolVal { + vector<ConstPoolUse> Val; + ConstPoolStruct(const ConstPoolStruct &CPT); +public: + ConstPoolStruct(const StructType *T, vector<ConstPoolVal*> &V, + const string &Name = ""); + inline ~ConstPoolStruct() { dropAllReferences(); } + + virtual ConstPoolVal *clone() const { return new ConstPoolStruct(*this); } + virtual string getStrValue() const; + virtual bool equals(const ConstPoolVal *V) const; + + inline const vector<ConstPoolUse> &getValues() const { return Val; } + + // Implement User stuff... + // + virtual Value *getOperand(unsigned i) { + return (i < Val.size()) ? Val[i] : 0; + } + virtual const Value *getOperand(unsigned i) const { + return (i < Val.size()) ? Val[i] : 0; + } + + // setOperand fails! You can't change a constant! + virtual bool setOperand(unsigned i, Value *Val) { return false; } + virtual void dropAllReferences() { Val.clear(); } +}; + +#endif diff --git a/include/llvm/ConstantHandling.h b/include/llvm/ConstantHandling.h new file mode 100644 index 0000000..3227e39 --- /dev/null +++ b/include/llvm/ConstantHandling.h @@ -0,0 +1,145 @@ +//===-- ConstantHandling.h - Stuff for manipulating constants ----*- C++ -*--=// +// +// This file contains the declarations of some cool operators that allow you +// to do natural things with constant pool values. +// +// Unfortunately we can't overload operators on pointer types (like this:) +// +// inline bool operator==(const ConstPoolVal *V1, const ConstPoolVal *V2) +// +// so we must make due with references, even though it leads to some butt ugly +// looking code downstream. *sigh* (ex: ConstPoolVal *Result = *V1 + *v2; ) +// +//===----------------------------------------------------------------------===// +// +// WARNING: These operators return pointers to newly 'new'd objects. You MUST +// make sure to free them if you don't want them hanging around. Also, +// note that these may return a null object if I don't know how to +// perform those operations on the specified constant types. +// +//===----------------------------------------------------------------------===// +// +// Implementation notes: +// This library is implemented this way for a reason: In most cases, we do +// not want to have to link the constant mucking code into an executable. +// We do, however want to tie some of this into the main type system, as an +// optional component. By using a mutable cache member in the Type class, we +// get exactly the kind of behavior we want. +// +// In the end, we get performance almost exactly the same as having a virtual +// function dispatch, but we don't have to put our virtual functions into the +// "Type" class, and we can implement functionality with templates. Good deal. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPT_CONSTANTHANDLING_H +#define LLVM_OPT_CONSTANTHANDLING_H + +#include "llvm/ConstPoolVals.h" +#include "llvm/Type.h" + +//===----------------------------------------------------------------------===// +// Implement == directly... +//===----------------------------------------------------------------------===// + +inline ConstPoolBool *operator==(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + assert(V1.getType() == V2.getType() && "Constant types must be identical!"); + return new ConstPoolBool(V1.equals(&V2)); +} + +//===----------------------------------------------------------------------===// +// Implement all other operators indirectly through TypeRules system +//===----------------------------------------------------------------------===// + +class ConstRules { +protected: + inline ConstRules() {} // Can only be subclassed... +public: + // Unary Operators... + virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0; + virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0; + + // Binary Operators... + virtual ConstPoolVal *add(const ConstPoolVal *V1, + const ConstPoolVal *V2) const = 0; + virtual ConstPoolVal *sub(const ConstPoolVal *V1, + const ConstPoolVal *V2) const = 0; + + virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, + const ConstPoolVal *V2) const = 0; + + // ConstRules::get - A type will cache its own type rules if one is needed... + // we just want to make sure to hit the cache instead of doing it indirectly, + // if possible... + // + static inline const ConstRules *get(const ConstPoolVal &V) { + const ConstRules *Result = V.getType()->getConstRules(); + return Result ? Result : find(V.getType()); + } +private : + static const ConstRules *find(const Type *Ty); + + ConstRules(const ConstRules &); // Do not implement + ConstRules &operator=(const ConstRules &); // Do not implement +}; + + +inline ConstPoolVal *operator-(const ConstPoolVal &V) { + return ConstRules::get(V)->neg(&V); +} + +inline ConstPoolVal *operator!(const ConstPoolVal &V) { + return ConstRules::get(V)->not(&V); +} + + + +inline ConstPoolVal *operator+(const ConstPoolVal &V1, const ConstPoolVal &V2) { + assert(V1.getType() == V2.getType() && "Constant types must be identical!"); + return ConstRules::get(V1)->add(&V1, &V2); +} + +inline ConstPoolVal *operator-(const ConstPoolVal &V1, const ConstPoolVal &V2) { + assert(V1.getType() == V2.getType() && "Constant types must be identical!"); + return ConstRules::get(V1)->sub(&V1, &V2); +} + +inline ConstPoolBool *operator<(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + assert(V1.getType() == V2.getType() && "Constant types must be identical!"); + return ConstRules::get(V1)->lessthan(&V1, &V2); +} + + +//===----------------------------------------------------------------------===// +// Implement 'derived' operators based on what we already have... +//===----------------------------------------------------------------------===// + +inline ConstPoolBool *operator>(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + return V2 < V1; +} + +inline ConstPoolBool *operator!=(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + ConstPoolBool *Result = V1 == V2; + Result->setValue(!Result->getValue()); // Invert value + return Result; // !(V1 == V2) +} + +inline ConstPoolBool *operator>=(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + ConstPoolBool *Result = V1 < V2; + Result->setValue(!Result->getValue()); // Invert value + return Result; // !(V1 < V2) +} + +inline ConstPoolBool *operator<=(const ConstPoolVal &V1, + const ConstPoolVal &V2) { + ConstPoolBool *Result = V1 > V2; + Result->setValue(!Result->getValue()); // Invert value + return Result; // !(V1 > V2) +} + +#endif diff --git a/include/llvm/ConstantPool.h b/include/llvm/ConstantPool.h new file mode 100644 index 0000000..7c8e255 --- /dev/null +++ b/include/llvm/ConstantPool.h @@ -0,0 +1,74 @@ +//===-- llvm/ConstantPool.h - Define the constant pool class ------*- C++ -*-=// +// +// This file implements a constant pool that is split into different type +// planes. This allows searching for a typed object to go a little faster. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CONSTANTPOOL_H +#define LLVM_CONSTANTPOOL_H + +#include <vector> +#include "llvm/ValueHolder.h" + +class ConstPoolVal; +class SymTabValue; +class Type; + +class ConstantPool { +public: + typedef ValueHolder<ConstPoolVal, SymTabValue> PlaneType; +private: + typedef vector<PlaneType*> PlanesType; + PlanesType Planes; + SymTabValue *Parent; + + inline void resize(unsigned size); +public: + inline ConstantPool(SymTabValue *P) { Parent = P; } + inline ~ConstantPool() { delete_all(); } + + inline SymTabValue *getParent() { return Parent; } + inline const SymTabValue *getParent() const { return Parent; } + + void setParent(SymTabValue *STV); + + void dropAllReferences(); // Drop all references to other constants + + // Constant getPlane - Returns true if the type plane does not exist, + // otherwise updates the pointer to point to the correct plane. + // + bool getPlane(const Type *T, const PlaneType *&Plane) const; + bool getPlane(const Type *T, PlaneType *&Plane); + + // Normal getPlane - Resizes constant pool to contain type even if it doesn't + // already have it. + // + PlaneType &getPlane(const Type *T); + + // insert - Add constant into the symbol table... + void insert(ConstPoolVal *N); + bool remove(ConstPoolVal *N); // Returns true on failure + + void delete_all(); + + // find - Search to see if a constant of the specified value is already in + // the constant table. + // + const ConstPoolVal *find(const ConstPoolVal *V) const; + ConstPoolVal *find(const ConstPoolVal *V) ; + const ConstPoolVal *find(const Type *Ty) const; + ConstPoolVal *find(const Type *Ty) ; + + // Plane iteration support + // + typedef PlanesType::iterator plane_iterator; + typedef PlanesType::const_iterator plane_const_iterator; + + inline plane_iterator begin() { return Planes.begin(); } + inline plane_const_iterator begin() const { return Planes.begin(); } + inline plane_iterator end() { return Planes.end(); } + inline plane_const_iterator end() const { return Planes.end(); } +}; + +#endif diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h new file mode 100644 index 0000000..c83a2d1 --- /dev/null +++ b/include/llvm/DerivedTypes.h @@ -0,0 +1,120 @@ +//===-- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*--=// +// +// This file contains the declarations of classes that represent "derived +// types". These are things like "arrays of x" or "structure of x, y, z" or +// "method returning x taking (y,z) as parameters", etc... +// +// The implementations of these classes live in the Type.cpp file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DERIVED_TYPES_H +#define LLVM_DERIVED_TYPES_H + +#include "llvm/Type.h" +#include <vector> + +// Future derived types: SIMD packed format + + +class MethodType : public Type { +public: + typedef vector<const Type*> ParamTypes; +private: + const Type *ResultType; + ParamTypes ParamTys; + + MethodType(const MethodType &); // Do not implement + const MethodType &operator=(const MethodType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class MethodType' only + // defines private constructors and has no friends + + // Private ctor - Only can be created by a static member... + MethodType(const Type *Result, const vector<const Type*> &Params, + const string &Name); +public: + + inline const Type *getReturnType() const { return ResultType; } + inline const ParamTypes &getParamTypes() const { return ParamTys; } + + static const MethodType *getMethodType(const Type *Result, + const ParamTypes &Params); +}; + + + +class ArrayType : public Type { +private: + const Type *ElementType; + int NumElements; // >= 0 for sized array, -1 for unbounded/unknown array + + ArrayType(const ArrayType &); // Do not implement + const ArrayType &operator=(const ArrayType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class ArrayType' only + // defines private constructors and has no friends + + + // Private ctor - Only can be created by a static member... + ArrayType(const Type *ElType, int NumEl, const string &Name); +public: + + inline const Type *getElementType() const { return ElementType; } + inline int getNumElements() const { return NumElements; } + + inline bool isSized() const { return NumElements >= 0; } + inline bool isUnsized() const { return NumElements == -1; } + + static const ArrayType *getArrayType(const Type *ElementType, + int NumElements = -1); +}; + +class StructType : public Type { +public: + typedef vector<const Type*> ElementTypes; +private: + ElementTypes ETypes; + + StructType(const StructType &); // Do not implement + const StructType &operator=(const StructType &); // Do not implement + +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class StructType' only + // defines private constructors and has no friends + + // Private ctor - Only can be created by a static member... + StructType(const vector<const Type*> &Types, const string &Name); +public: + + inline const ElementTypes &getElementTypes() const { return ETypes; } + static const StructType *getStructType(const ElementTypes &Params); +}; + + +class PointerType : public Type { +private: + const Type *ValueType; + + PointerType(const PointerType &); // Do not implement + const PointerType &operator=(const PointerType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class PointerType' only + // defines private constructors and has no friends + + + // Private ctor - Only can be created by a static member... + PointerType(const Type *ElType); +public: + + inline const Type *getValueType() const { return ValueType; } + + + static const PointerType *getPointerType(const Type *ElementType); +}; + +#endif diff --git a/include/llvm/Function.h b/include/llvm/Function.h new file mode 100644 index 0000000..7448dce --- /dev/null +++ b/include/llvm/Function.h @@ -0,0 +1,174 @@ +//===-- llvm/Method.h - Class to represent a single VM method ----*- C++ -*--=// +// +// This file contains the declaration of the Method class, which represents a +// single Method/function/procedure in the VM. +// +// Note that basic blocks themselves are Def's, because they are referenced +// by instructions like calls and can go in virtual function tables and stuff. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_METHOD_H +#define LLVM_METHOD_H + +#include "llvm/SymTabValue.h" +#include "llvm/BasicBlock.h" +#include <list> + +class Instruction; +class BasicBlock; +class MethodArgument; +class MethodType; +class Method; +class Module; + +typedef UseTy<Method> MethodUse; + +class Method : public SymTabValue { +public: + typedef ValueHolder<MethodArgument, Method> ArgumentListType; + typedef ValueHolder<BasicBlock , Method> BasicBlocksType; +private: + + // Important things that make up a method! + BasicBlocksType BasicBlocks; // The basic blocks + ArgumentListType ArgumentList; // The formal arguments + + Module *Parent; // The module that contains this method + + friend class ValueHolder<Method,Module>; + void setParent(Module *parent); + +public: + Method(const MethodType *Ty, const string &Name = ""); + ~Method(); + + // Specialize setName to handle symbol table majik... + virtual void setName(const string &name); + + const Type *getReturnType() const; + const MethodType *getMethodType() const; + + // Is the body of this method unknown? (the basic block list is empty if so) + // this is true for "extern"al methods. + bool isMethodExternal() const { return BasicBlocks.empty(); } + + + // Get the class structure that this method is contained inside of... + inline Module *getParent() { return Parent; } + inline const Module *getParent() const { return Parent; } + + inline const BasicBlocksType &getBasicBlocks() const { return BasicBlocks; } + inline BasicBlocksType &getBasicBlocks() { return BasicBlocks; } + + inline const ArgumentListType &getArgumentList() const{ return ArgumentList; } + inline ArgumentListType &getArgumentList() { return ArgumentList; } + + + // 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(); + + //===--------------------------------------------------------------------===// + // Method Instruction iterator code + //===--------------------------------------------------------------------===// + // + template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> + class InstIterator; + typedef InstIterator<BasicBlocksType, BasicBlocksType::iterator, + BasicBlock::InstListType::iterator, + Instruction*> inst_iterator; + typedef InstIterator<const BasicBlocksType, BasicBlocksType::const_iterator, + BasicBlock::InstListType::const_iterator, + const Instruction*> inst_const_iterator; + + // This inner class is used to implement inst_begin() & inst_end() for + // inst_iterator and inst_const_iterator's. + // + template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> + class InstIterator { + typedef _BB_t BBty; + typedef _BB_i_t BBIty; + typedef _BI_t BIty; + typedef _II_t IIty; + _BB_t &BBs; // BasicBlocksType + _BB_i_t BB; // BasicBlocksType::iterator + _BI_t BI; // BasicBlock::InstListType::iterator + public: + typedef bidirectional_iterator_tag iterator_category; + + template<class M> InstIterator(M &m) + : BBs(m.getBasicBlocks()), BB(BBs.begin()) { // begin ctor + if (BB != BBs.end()) { + BI = (*BB)->getInstList().begin(); + resyncInstructionIterator(); + } + } + + template<class M> InstIterator(M &m, bool) + : BBs(m.getBasicBlocks()), BB(BBs.end()) { // end ctor + } + + // Accessors to get at the underlying iterators... + inline BBIty &getBasicBlockIterator() { return BB; } + inline BIty &getInstructionIterator() { return BI; } + + inline IIty operator*() const { return *BI; } + inline IIty *operator->() const { return &(operator*()); } + + inline bool operator==(const InstIterator &y) const { + return BB == y.BB && (BI == y.BI || BB == BBs.end()); + } + inline bool operator!=(const InstIterator& y) const { + return !operator==(y); + } + + // resyncInstructionIterator - This should be called if the + // InstructionIterator is modified outside of our control. This resynchs + // the internals of the InstIterator to a consistent state. + // + inline void resyncInstructionIterator() { + // The only way that the II could be broken is if it is now pointing to + // the end() of the current BasicBlock and there are successor BBs. + while (BI == (*BB)->getInstList().end()) { + ++BB; + if (BB == BBs.end()) break; + BI = (*BB)->getInstList().begin(); + } + } + + InstIterator& operator++() { + ++BI; + resyncInstructionIterator(); // Make sure it is still valid. + return *this; + } + inline InstIterator operator++(int) { + InstIterator tmp = *this; ++*this; return tmp; + } + + InstIterator& operator--() { + while (BB == BBs.end() || BI == (*BB)->getInstList().begin()) { + --BB; + BI = (*BB)->getInstList().end(); + } + --BI; + return *this; + } + inline InstIterator operator--(int) { + InstIterator tmp = *this; --*this; return tmp; + } + }; + + inline inst_iterator inst_begin() { return inst_iterator(*this); } + inline inst_iterator inst_end() { return inst_iterator(*this, true); } + inline inst_const_iterator inst_begin() const { return inst_const_iterator(*this); } + inline inst_const_iterator inst_end() const { return inst_const_iterator(*this, true); } +}; + +#endif diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h new file mode 100644 index 0000000..be6ea26 --- /dev/null +++ b/include/llvm/InstrTypes.h @@ -0,0 +1,131 @@ +//===-- llvm/InstrTypes.h - Important Instruction subclasses -----*- C++ -*--=// +// +// This file defines various meta classes of instructions that exist in the VM +// representation. Specific concrete subclasses of these may be found in the +// i*.h files... +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INSTRUCTION_TYPES_H +#define LLVM_INSTRUCTION_TYPES_H + +#include "llvm/Instruction.h" +#include <list> +#include <vector> + +class Method; +class SymTabValue; + +//===----------------------------------------------------------------------===// +// TerminatorInst Class +//===----------------------------------------------------------------------===// + +// TerminatorInst - Subclasses of this class are all able to terminate a basic +// block. Thus, these are all the flow control type of operations. +// +class TerminatorInst : public Instruction { +public: + TerminatorInst(unsigned iType); + inline ~TerminatorInst() {} + + // Terminators must implement the methods required by Instruction... + virtual Instruction *clone() const = 0; + virtual void dropAllReferences() = 0; + virtual string getOpcode() const = 0; + + virtual bool setOperand(unsigned i, Value *Val) = 0; + virtual const Value *getOperand(unsigned i) const = 0; + + // Additionally, they must provide a method to get at the successors of this + // terminator instruction. If 'idx' is out of range, a null pointer shall be + // returned. + // + virtual const BasicBlock *getSuccessor(unsigned idx) const = 0; + virtual unsigned getNumSuccessors() const = 0; + + inline BasicBlock *getSuccessor(unsigned idx) { + return (BasicBlock*)((const TerminatorInst *)this)->getSuccessor(idx); + } +}; + + +//===----------------------------------------------------------------------===// +// UnaryOperator Class +//===----------------------------------------------------------------------===// + +class UnaryOperator : public Instruction { + Use Source; +public: + UnaryOperator(Value *S, unsigned iType, const string &Name = "") + : Instruction(S->getType(), iType, Name), Source(S, this) { + } + inline ~UnaryOperator() { dropAllReferences(); } + + virtual Instruction *clone() const { + return Instruction::getUnaryOperator(getInstType(), Source); + } + + virtual void dropAllReferences() { + Source = 0; + } + + virtual string getOpcode() const = 0; + + virtual unsigned getNumOperands() const { return 1; } + virtual const Value *getOperand(unsigned i) const { + return (i == 0) ? Source : 0; + } + virtual bool setOperand(unsigned i, Value *Val) { + // assert(Val && "operand must not be null!"); + if (i) return false; + Source = Val; + return true; + } +}; + + + +//===----------------------------------------------------------------------===// +// BinaryOperator Class +//===----------------------------------------------------------------------===// + +class BinaryOperator : public Instruction { + Use Source1, Source2; +public: + BinaryOperator(unsigned iType, Value *S1, Value *S2, + const string &Name = "") + : Instruction(S1->getType(), iType, Name), Source1(S1, this), + Source2(S2, this){ + assert(S1 && S2 && S1->getType() == S2->getType()); + } + inline ~BinaryOperator() { dropAllReferences(); } + + virtual Instruction *clone() const { + return Instruction::getBinaryOperator(getInstType(), Source1, Source2); + } + + virtual void dropAllReferences() { + Source1 = Source2 = 0; + } + + virtual string getOpcode() const = 0; + + virtual unsigned getNumOperands() const { return 2; } + virtual const Value *getOperand(unsigned i) const { + return (i == 0) ? Source1 : ((i == 1) ? Source2 : 0); + } + + virtual bool setOperand(unsigned i, Value *Val) { + // assert(Val && "operand must not be null!"); + if (i == 0) { + Source1 = Val; //assert(Val->getType() == Source2->getType()); + } else if (i == 1) { + Source2 = Val; //assert(Val->getType() == Source1->getType()); + } else { + return false; + } + return true; + } +}; + +#endif diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h new file mode 100644 index 0000000..415c307 --- /dev/null +++ b/include/llvm/Instruction.h @@ -0,0 +1,199 @@ +//===-- llvm/Instruction.h - Instruction class definition --------*- C++ -*--=// +// +// This file contains the declaration of the Instruction class, which is the +// base class for all of the VM instructions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INSTRUCTION_H +#define LLVM_INSTRUCTION_H + +#include "llvm/User.h" + +class Type; +class BasicBlock; +class Method; + +class Instruction : public User { + BasicBlock *Parent; + unsigned iType; // InstructionType + + friend class ValueHolder<Instruction,BasicBlock>; + inline void setParent(BasicBlock *P) { Parent = P; } + +public: + Instruction(const Type *Ty, unsigned iType, const string &Name = ""); + virtual ~Instruction(); // Virtual dtor == good. + + // Specialize setName to handle symbol table majik... + virtual void setName(const string &name); + + // clone() - Create a copy of 'this' instruction that is identical in all ways + // except the following: + // * The instruction has no parent + // * The instruction has no name + // + virtual Instruction *clone() const = 0; + + // Accessor methods... + // + inline const BasicBlock *getParent() const { return Parent; } + inline BasicBlock *getParent() { return Parent; } + bool hasSideEffects() const { return false; } // Memory & Call insts = true + + // --------------------------------------------------------------------------- + // Implement the User interface + // if i > the number of operands, then getOperand() returns 0, and setOperand + // returns false. setOperand() may also return false if the operand is of + // the wrong type. + // + inline Value *getOperand(unsigned i) { + return (Value*)((const Instruction *)this)->getOperand(i); + } + virtual const Value *getOperand(unsigned i) const = 0; + virtual bool setOperand(unsigned i, Value *Val) = 0; + virtual unsigned getNumOperands() const = 0; + + // --------------------------------------------------------------------------- + // Operand Iterator interface... + // + template <class _Inst, class _Val> class OperandIterator; + typedef OperandIterator<Instruction *, Value *> op_iterator; + typedef OperandIterator<const Instruction *, const Value *> op_const_iterator; + + inline op_iterator op_begin() ; + inline op_const_iterator op_begin() const; + inline op_iterator op_end() ; + inline op_const_iterator op_end() const; + + + // --------------------------------------------------------------------------- + // Subclass classification... getInstType() returns a member of + // one of the enums that is coming soon (down below)... + // + virtual string getOpcode() const = 0; + + unsigned getInstType() const { return iType; } + inline bool isTerminator() const { // Instance of TerminatorInst? + return iType >= FirstTermOp && iType < NumTermOps; + } + inline bool isDefinition() const { return !isTerminator(); } + inline bool isUnaryOp() const { + return iType >= FirstUnaryOp && iType < NumUnaryOps; + } + inline bool isBinaryOp() const { + return iType >= FirstBinaryOp && iType < NumBinaryOps; + } + + static Instruction *getBinaryOperator(unsigned Op, Value *S1, Value *S2); + static Instruction *getUnaryOperator (unsigned Op, Value *Source); + + + //---------------------------------------------------------------------- + // Exported enumerations... + // + enum TermOps { // These terminate basic blocks + FirstTermOp = 1, + Ret = 1, Br, Switch, + NumTermOps // Must remain at end of enum + }; + + enum UnaryOps { + FirstUnaryOp = NumTermOps, + Neg = NumTermOps, Not, + + // Type conversions... + ToBoolTy , + ToUByteTy , ToSByteTy, ToUShortTy, ToShortTy, + ToUInt , ToInt, ToULongTy , ToLongTy, + + ToFloatTy , ToDoubleTy, ToArrayTy , ToPointerTy, + + NumUnaryOps // Must remain at end of enum + }; + + enum BinaryOps { + // Standard binary operators... + FirstBinaryOp = NumUnaryOps, + Add = NumUnaryOps, Sub, Mul, Div, Rem, + + // Logical operators... + And, Or, Xor, + + // Binary comparison operators... + SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT, + + NumBinaryOps + }; + + enum MemoryOps { + FirstMemoryOp = NumBinaryOps, + Malloc = NumBinaryOps, Free, // Heap management instructions + Alloca, // Stack management instruction + + Load, Store, // Memory manipulation instructions. + + GetField, PutField, // Structure manipulation instructions + + NumMemoryOps + }; + + enum OtherOps { + FirstOtherOp = NumMemoryOps, + PHINode = NumMemoryOps, // PHI node instruction + Call, // Call a function + + Shl, Shr, // Shift operations... + + NumOps, // Must be the last 'op' defined. + UserOp1, UserOp2 // May be used internally to a pass... + }; + +public: + template <class _Inst, class _Val> // Operand Iterator Implementation + class OperandIterator { + const _Inst Inst; + unsigned idx; + public: + typedef OperandIterator<_Inst, _Val> _Self; + typedef forward_iterator_tag iterator_category; + typedef _Val pointer; + + inline OperandIterator(_Inst T) : Inst(T), idx(0) {} // begin iterator + inline OperandIterator(_Inst T, bool) + : Inst(T), idx(Inst->getNumOperands()) {} // 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 Inst->getOperand(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; + } + }; + +}; + +inline Instruction::op_iterator Instruction::op_begin() { + return op_iterator(this); +} +inline Instruction::op_const_iterator Instruction::op_begin() const { + return op_const_iterator(this); +} +inline Instruction::op_iterator Instruction::op_end() { + return op_iterator(this,true); +} +inline Instruction::op_const_iterator Instruction::op_end() const { + return op_const_iterator(this,true); +} + + +#endif diff --git a/include/llvm/Module.h b/include/llvm/Module.h new file mode 100644 index 0000000..9437b2c --- /dev/null +++ b/include/llvm/Module.h @@ -0,0 +1,38 @@ +//===-- llvm/Module.h - C++ class to represent a VM module -------*- C++ -*--=// +// +// This file contains the declarations for the Module class that is used to +// maintain all the information related to a VM module. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MODULE_H +#define LLVM_MODULE_H + +#include "llvm/SymTabValue.h" +class Method; + +class Module : public SymTabValue { +public: + typedef ValueHolder<Method, Module> MethodListType; +private: + MethodListType MethodList; // The Methods + +public: + Module(); + ~Module(); + + inline const MethodListType &getMethodList() const { return MethodList; } + inline MethodListType &getMethodList() { return MethodList; } + + // 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(); +}; + +#endif diff --git a/include/llvm/Optimizations/AllOpts.h b/include/llvm/Optimizations/AllOpts.h new file mode 100644 index 0000000..bfb7b57 --- /dev/null +++ b/include/llvm/Optimizations/AllOpts.h @@ -0,0 +1,95 @@ +//===-- llvm/AllOpts.h - Header file to get all opt passes -------*- C++ -*--=// +// +// This file #include's all of the small optimization header files. +// +// Note that all optimizations return true if they modified the program, false +// if not. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPT_ALLOPTS_H +#define LLVM_OPT_ALLOPTS_H + +#include "llvm/Module.h" +#include "llvm/BasicBlock.h" +class Method; +class CallInst; + +//===----------------------------------------------------------------------===// +// Helper functions +// + +static inline bool ApplyOptToAllMethods(Module *C, bool (*Opt)(Method*)) { + bool Modified = false; + for (Module::MethodListType::iterator I = C->getMethodList().begin(); + I != C->getMethodList().end(); I++) + Modified |= Opt(*I); + return Modified; +} + +//===----------------------------------------------------------------------===// +// Dead Code Elimination Pass +// + +bool DoDeadCodeElimination(Method *M); // DCE a method +bool DoRemoveUnusedConstants(SymTabValue *S); // RUC a method or class +bool DoDeadCodeElimination(Module *C); // DCE & RUC a whole class + +//===----------------------------------------------------------------------===// +// Constant Propogation Pass +// + +bool DoConstantPropogation(Method *M); + +static inline bool DoConstantPropogation(Module *C) { + return ApplyOptToAllMethods(C, DoConstantPropogation); +} + +//===----------------------------------------------------------------------===// +// Method Inlining Pass +// + +// DoMethodInlining - Use a heuristic based approach to inline methods that seem +// to look good. +// +bool DoMethodInlining(Method *M); + +static inline bool DoMethodInlining(Module *C) { + return ApplyOptToAllMethods(C, DoMethodInlining); +} + +// InlineMethod - This function forcibly inlines the called method into the +// basic block of the caller. This returns true if it is not possible to inline +// this call. The program is still in a well defined state if this occurs +// though. +// +// Note that this only does one level of inlining. For example, if the +// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now +// exists in the instruction stream. Similiarly this will inline a recursive +// method by one level. +// +bool InlineMethod(CallInst *C); +bool InlineMethod(BasicBlock::InstListType::iterator CI);// *CI must be CallInst + + +//===----------------------------------------------------------------------===// +// Symbol Stripping Pass +// + +// DoSymbolStripping - Remove all symbolic information from a method +// +bool DoSymbolStripping(Method *M); + +// DoSymbolStripping - Remove all symbolic information from all methods in a +// module +// +static inline bool DoSymbolStripping(Module *M) { + return ApplyOptToAllMethods(M, DoSymbolStripping); +} + +// DoFullSymbolStripping - Remove all symbolic information from all methods +// in a module, and all module level symbols. (method names, etc...) +// +bool DoFullSymbolStripping(Module *M); + +#endif diff --git a/include/llvm/SlotCalculator.h b/include/llvm/SlotCalculator.h new file mode 100644 index 0000000..99e40cb --- /dev/null +++ b/include/llvm/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/SymTabValue.h b/include/llvm/SymTabValue.h new file mode 100644 index 0000000..556d5c7 --- /dev/null +++ b/include/llvm/SymTabValue.h @@ -0,0 +1,51 @@ +//===-- llvm/SymTabDef.h - Implement SymbolTable Defs ------------*- C++ -*--=// +// +// This subclass of Def implements a def that has a symbol table for keeping +// track of children. This is used by the DefHolder template class... +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYMTABDEF_H +#define LLVM_SYMTABDEF_H + +#include "llvm/Value.h" // Get the definition of Value +#include "llvm/ConstantPool.h" + +class SymbolTable; +class ConstPoolVal; + +class SymTabValue : public Value { +public: + typedef ConstantPool ConstantPoolType; +private: + SymbolTable *SymTab, *ParentSymTab; + ConstantPool ConstPool; // The constant pool + +protected: + void setParentSymTab(SymbolTable *ST); +public: + SymTabValue(const Type *Ty, ValueTy dty, const string &name = ""); + ~SymTabValue(); // Implemented in Def.cpp + + // hasSymbolTable() - Returns true if there is a symbol table allocated to + // this object AND if there is at least one name in it! + // + bool hasSymbolTable() const; + + // CAUTION: The current symbol table may be null if there are no names (ie, + // the symbol table is empty) + // + inline SymbolTable *getSymbolTable() { return SymTab; } + inline const SymbolTable *getSymbolTable() const { return SymTab; } + + inline const ConstantPool &getConstantPool() const{ return ConstPool; } + inline ConstantPool &getConstantPool() { return ConstPool; } + + // getSymbolTableSure is guaranteed to not return a null pointer, because if + // the method does not already have a symtab, one is created. Use this if + // you intend to put something into the symbol table for the method. + // + SymbolTable *getSymbolTableSure(); // Implemented in Def.cpp +}; + +#endif diff --git a/include/llvm/SymbolTable.h b/include/llvm/SymbolTable.h new file mode 100644 index 0000000..dfb78ee --- /dev/null +++ b/include/llvm/SymbolTable.h @@ -0,0 +1,83 @@ +//===-- llvm/SymbolTable.h - Implement a type planed symtab -------*- C++ -*-=// +// +// This file implements a symbol table that has planed broken up by type. +// Identical types may have overlapping symbol names as long as they are +// distinct. +// +// Note that this implements a chained symbol table. If a name being 'lookup'd +// isn't found in the current symbol table, then the parent symbol table is +// searched. +// +// This chaining behavior does NOT affect iterators though: only the lookup +// method +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYMBOL_TABLE_H +#define LLVM_SYMBOL_TABLE_H + +#include <vector> +#include <map> +#include <string> + +class Value; +class Type; + +// TODO: Change this back to vector<map<const string, Value *> > +// Make the vector be a data member, and base it on UniqueID's +// That should be much more efficient! +// +class SymbolTable : public map<const Type *, map<const string, Value *> > { + typedef map<const string, Value *> VarMap; + typedef map<const Type *, VarMap> super; + + SymbolTable *ParentSymTab; + + friend class SymTabValue; + inline void setParentSymTab(SymbolTable *P) { ParentSymTab = P; } + +public: + typedef VarMap::iterator type_iterator; + typedef VarMap::const_iterator type_const_iterator; + + inline SymbolTable(SymbolTable *P = 0) { ParentSymTab = P; } + ~SymbolTable(); + + SymbolTable *getParentSymTab() { return ParentSymTab; } + + // lookup - Returns null on failure... + Value *lookup(const Type *Ty, const string &name); + + // find - returns end(Ty->getIDNumber()) on failure... + type_iterator type_find(const Type *Ty, const string &name); + type_iterator type_find(const Value *D); + + // insert - Add named definition to the symbol table... + void insert(Value *N); + + void remove(Value *N); + Value *type_remove(const type_iterator &It); + + inline unsigned type_size(const Type *TypeID) const { + return find(TypeID)->second.size(); + } + + // Note that type_begin / type_end only work if you know that an element of + // TypeID is already in the symbol table!!! + // + inline type_iterator type_begin(const Type *TypeID) { + return find(TypeID)->second.begin(); + } + inline type_const_iterator type_begin(const Type *TypeID) const { + return find(TypeID)->second.begin(); + } + + inline type_iterator type_end(const Type *TypeID) { + return find(TypeID)->second.end(); + } + inline type_const_iterator type_end(const Type *TypeID) const { + return find(TypeID)->second.end(); + } +}; + +#endif diff --git a/include/llvm/Tools/CommandLine.h b/include/llvm/Tools/CommandLine.h new file mode 100644 index 0000000..76b4e97 --- /dev/null +++ b/include/llvm/Tools/CommandLine.h @@ -0,0 +1,126 @@ +//===-- llvm/Tools/CommandLine.h - Command line parser for tools -*- C++ -*--=// +// +// This class implements a command line argument processor that is useful when +// creating a tool. +// +// This class is defined entirely inline so that you don't have to link to any +// libraries to use this. +// +// TODO: make this extensible by passing in arguments to be read. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_COMMANDLINE_H +#define LLVM_TOOLS_COMMANDLINE_H + +#include <string> + +class ToolCommandLine { +public: + inline ToolCommandLine(int &argc, char **argv, bool OutputBytecode = true); + inline ToolCommandLine(const string &infn, const string &outfn = "-"); + inline ToolCommandLine(const ToolCommandLine &O); + inline ToolCommandLine &operator=(const ToolCommandLine &O); + + inline bool getForce() const { return Force; } + inline const string getInputFilename() const { return InputFilename; } + inline const string getOutputFilename() const { return OutputFilename; } + +private: + void calculateOutputFilename(bool OutputBytecode) { + OutputFilename = InputFilename; + unsigned Len = OutputFilename.length(); + + if (Len <= 3) { + OutputFilename += (OutputBytecode ? ".bc" : ".ll"); + return; + } + + if (OutputBytecode) { + if (OutputFilename[Len-3] == '.' && + OutputFilename[Len-2] == 'l' && + OutputFilename[Len-1] == 'l') { // .ll -> .bc + OutputFilename[Len-2] = 'b'; + OutputFilename[Len-1] = 'c'; + } else { + OutputFilename += ".bc"; + } + } else { + if (OutputFilename[Len-3] == '.' && + OutputFilename[Len-2] == 'b' && + OutputFilename[Len-1] == 'c') { // .ll -> .bc + OutputFilename[Len-2] = 'l'; + OutputFilename[Len-1] = 'l'; + } else { + OutputFilename += ".ll"; + } + } + } + +private: + string InputFilename; // Filename to read from. If "-", use stdin. + string OutputFilename; // Filename to write to. If "-", use stdout. + bool Force; // Force output (-f argument) +}; + +inline ToolCommandLine::ToolCommandLine(int &argc, char **argv, bool OutBC) + : InputFilename("-"), OutputFilename("-"), Force(false) { + bool FoundInputFN = false; + bool FoundOutputFN = false; + bool FoundForce = false; + + for (int i = 1; i < argc; i++) { + int RemoveArg = 0; + + if (argv[i][0] == '-') { + if (!FoundInputFN && argv[i][1] == 0) { // Is the current argument '-' + InputFilename = argv[i]; + FoundInputFN = true; + RemoveArg = 1; + } else if (!FoundOutputFN && (argv[i][1] == 'o' && argv[i][2] == 0)) { + // Is the argument -o? + if (i+1 < argc) { // Next arg is output fn + OutputFilename = argv[i+1]; + FoundOutputFN = true; + RemoveArg = 2; + } + } else if (!FoundForce && (argv[i][1] == 'f' && argv[i][2] == 0)) { + Force = true; + FoundForce = true; + RemoveArg = 1; + } + } else if (!FoundInputFN) { // Is the current argument '[^-].*'? + InputFilename = argv[i]; + FoundInputFN = true; + RemoveArg = 1; + } + + if (RemoveArg) { + argc -= RemoveArg; // Shift args over... + memmove(argv+i, argv+i+RemoveArg, (argc-i)*sizeof(char*)); + i--; // Reprocess this argument... + } + } + + if (!FoundOutputFN && InputFilename != "-") + calculateOutputFilename(OutBC); +} + +inline ToolCommandLine::ToolCommandLine(const string &inf, + const string &outf) + : InputFilename(inf), OutputFilename(outf), Force(false) { +} + +inline ToolCommandLine::ToolCommandLine(const ToolCommandLine &Opts) + : InputFilename(Opts.InputFilename), OutputFilename(Opts.OutputFilename), + Force(Opts.Force) { +} + +inline ToolCommandLine &ToolCommandLine::operator=(const ToolCommandLine &Opts){ + InputFilename = Opts.InputFilename; + OutputFilename = Opts.OutputFilename; + Force = Opts.Force; + return *this; +} + +#endif diff --git a/include/llvm/Tools/DataTypes.h b/include/llvm/Tools/DataTypes.h new file mode 100644 index 0000000..ada16c2 --- /dev/null +++ b/include/llvm/Tools/DataTypes.h @@ -0,0 +1,26 @@ + +// TODO: This file sucks. Not only does it not work, but this stuff should be +// autoconfiscated anyways. Major FIXME + + +#ifndef LLVM_TOOLS_DATATYPES_H +#define LLVM_TOOLS_DATATYPES_H + +// Should define the following: +// LITTLE_ENDIAN if applicable +// int64_t +// uint64_t + +#ifdef LINUX +#include <stdint.h> // Defined by ISO C 99 +#include <endian.h> + +#else +#include <sys/types.h> +#ifdef _LITTLE_ENDIAN +#define LITTLE_ENDIAN 1 +#endif +#endif + + +#endif diff --git a/include/llvm/Tools/StringExtras.h b/include/llvm/Tools/StringExtras.h new file mode 100644 index 0000000..31dedb4 --- /dev/null +++ b/include/llvm/Tools/StringExtras.h @@ -0,0 +1,63 @@ +//===-- StringExtras.h - Useful string functions -----------------*- C++ -*--=// +// +// This file contains some functions that are useful when dealing with strings. +// No library is required when using these functinons. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_STRING_EXTRAS_H +#define LLVM_TOOLS_STRING_EXTRAS_H + +#include <string> +#include "llvm/Tools/DataTypes.h" + +static inline string utostr(uint64_t X, bool isNeg = false) { + char Buffer[40]; + char *BufPtr = Buffer+39; + + *BufPtr = 0; // Null terminate buffer... + if (X == 0) *--BufPtr = '0'; // Handle special case... + + while (X) { + *--BufPtr = '0' + (X % 10); + X /= 10; + } + + if (isNeg) *--BufPtr = '-'; // Add negative sign... + + return string(BufPtr); +} + +static inline string itostr(int64_t X) { + if (X < 0) + return utostr((uint64_t)-X, true); + else + return utostr((uint64_t)X); +} + + +static inline string utostr(unsigned X, bool isNeg = false) { + char Buffer[20]; + char *BufPtr = Buffer+19; + + *BufPtr = 0; // Null terminate buffer... + if (X == 0) *--BufPtr = '0'; // Handle special case... + + while (X) { + *--BufPtr = '0' + (X % 10); + X /= 10; + } + + if (isNeg) *--BufPtr = '-'; // Add negative sign... + + return string(BufPtr); +} + +static inline string itostr(int X) { + if (X < 0) + return utostr((unsigned)-X, true); + else + return utostr((unsigned)X); +} + +#endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h new file mode 100644 index 0000000..40555b0 --- /dev/null +++ b/include/llvm/Type.h @@ -0,0 +1,116 @@ +//===-- llvm/Type.h - Classes for handling data types ------------*- C++ -*--=// +// +// This file contains the declaration of the Type class. For more "Type" type +// stuff, look in DerivedTypes.h and Opt/ConstantHandling.h +// +// Note that instances of the Type class are immutable: once they are created, +// they are never changed. Also note that only one instance of a particular +// type is ever created. Thus seeing if two types are equal is a matter of +// doing a trivial pointer comparison. +// +// Types, once allocated, are never free'd. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TYPE_H +#define LLVM_TYPE_H + +#include "llvm/Value.h" + +class ConstRules; +class ConstPoolVal; + +class Type : public Value { +public: + //===--------------------------------------------------------------------===// + // Definitions of all of the base types for the Type system. Based on this + // value, you can cast to a "DerivedType" subclass (see DerivedTypes.h) + // Note: If you add an element to this, you need to add an element to the + // Type::getPrimitiveType function, or else things will break! + // + enum PrimitiveID { + VoidTyID = 0 , BoolTyID, // 0, 1: Basics... + UByteTyID , SByteTyID, // 2, 3: 8 bit types... + UShortTyID , ShortTyID, // 4, 5: 16 bit types... + UIntTyID , IntTyID, // 6, 7: 32 bit types... + ULongTyID , LongTyID, // 8, 9: 64 bit types... + + FloatTyID , DoubleTyID, // 10,11: Floating point types... + + TypeTyID, // 12 : Type definitions + LabelTyID , LockTyID, // 13,14: Labels... mutexes... + + // TODO: Kill FillerTyID. It just makes FirstDerivedTyID = 0x10 + FillerTyID , // 15 : filler + + // Derived types... see DerivedTypes.h file... + // Make sure FirstDerivedTyID stays up to date!!! + MethodTyID , ModuleTyID, // Methods... Modules... + ArrayTyID , PointerTyID, // Array... pointer... + StructTyID , PackedTyID, // Structure... SIMD 'packed' format... + //... + + NumPrimitiveIDs, // Must remain as last defined ID + FirstDerivedTyID = MethodTyID, + }; + +private: + PrimitiveID ID; // The current base type of this type... + unsigned UID; // The unique ID number for this class + + // ConstRulesImpl - See Opt/ConstantHandling.h for more info + mutable const ConstRules *ConstRulesImpl; + +protected: + // ctor is protected, so only subclasses can create Type objects... + Type(const string &Name, PrimitiveID id); +public: + virtual ~Type() {} + + // isSigned - Return whether a numeric type is signed. + virtual bool isSigned() const { return 0; } + + // isUnsigned - Return whether a numeric type is unsigned. This is not + // quite the complement of isSigned... nonnumeric types return false as they + // do with isSigned. + // + virtual bool isUnsigned() const { return 0; } + + inline unsigned getUniqueID() const { return UID; } + inline PrimitiveID getPrimitiveID() const { return ID; } + + // getPrimitiveType/getUniqueIDType - Return a type based on an identifier. + static const Type *getPrimitiveType(PrimitiveID IDNumber); + static const Type *getUniqueIDType(unsigned UID); + + // Methods for dealing with constants uniformly. See Opt/ConstantHandling.h + // for more info on this... + // + inline const ConstRules *getConstRules() const { return ConstRulesImpl; } + inline void setConstRules(const ConstRules *R) const { ConstRulesImpl = R; } + +public: // These are the builtin types that are always available... + static const Type *VoidTy , *BoolTy; + static const Type *SByteTy, *UByteTy, + *ShortTy, *UShortTy, + *IntTy , *UIntTy, + *LongTy , *ULongTy; + static const Type *FloatTy, *DoubleTy; + + static const Type *TypeTy , *LabelTy, *LockTy; + + // Here are some useful little methods to query what type derived types are + // Note that all other types can just compare to see if this == Type::xxxTy; + // + inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } + inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; } + + inline bool isLabelType() const { return this == LabelTy; } + inline bool isMethodType() const { return ID == MethodTyID; } + inline bool isModuleType() const { return ID == ModuleTyID; } + inline bool isArrayType() const { return ID == ArrayTyID; } + inline bool isPointerType() const { return ID == PointerTyID; } + inline bool isStructType() const { return ID == StructTyID; } +}; + +#endif diff --git a/include/llvm/User.h b/include/llvm/User.h new file mode 100644 index 0000000..58e0dec --- /dev/null +++ b/include/llvm/User.h @@ -0,0 +1,47 @@ +//===-- llvm/User.h - User class definition ----------------------*- C++ -*--=// +// +// This class defines the interface that one who 'use's a Value must implement. +// Each instance of the Value class keeps track of what User's have handles +// to it. +// +// * Instructions are the largest class of User's. +// * Constants may be users of other constants (think arrays and stuff) +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_USER_H +#define LLVM_USER_H + +#include "llvm/Value.h" + +class User : public Value { + User(const User &); // Do not implement +public: + User(const Type *Ty, ValueTy vty, const string &name = ""); + virtual ~User() {} + + // if i > the number of operands, then getOperand() returns 0, and setOperand + // returns false. setOperand() may also return false if the operand is of + // the wrong type. + // + virtual Value *getOperand(unsigned i) = 0; + virtual const Value *getOperand(unsigned i) const = 0; + virtual bool setOperand(unsigned i, Value *Val) = 0; + + // dropAllReferences() - This virtual function should be overridden to "let + // go" of all references that this user is 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. + // + virtual void dropAllReferences() = 0; + + // replaceUsesOfWith - Replaces all references to the "From" definition with + // references to the "To" definition. (defined in Value.cpp) + // + void replaceUsesOfWith(Value *From, Value *To); +}; + +#endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h new file mode 100644 index 0000000..d751eb1 --- /dev/null +++ b/include/llvm/Value.h @@ -0,0 +1,124 @@ +//===-- llvm/Value.h - Definition of the Value class -------------*- C++ -*--=// +// +// This file defines the very important Value class. This is subclassed by a +// bunch of other important classes, like Def, Method, Module, Type, etc... +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_VALUE_H +#define LLVM_VALUE_H + +#include <string> +#include <list> + +class User; +class Type; +template<class ValueSubclass, class ItemParentType> class ValueHolder; + +//===----------------------------------------------------------------------===// +// Value Class +//===----------------------------------------------------------------------===// + +class Value { +public: + enum ValueTy { + TypeVal, // This is an instance of Type + ConstantVal, // This is an instance of ConstPoolVal + MethodArgumentVal, // This is an instance of MethodArgument + InstructionVal, // This is an instance of Instruction + + BasicBlockVal, // This is an instance of BasicBlock + MethodVal, // This is an instance of Method + ModuleVal, // This is an instance of Module + }; + +private: + list<User *> Uses; + string Name; + const Type *Ty; + ValueTy VTy; + + Value(const Value &); // Do not implement +protected: + inline void setType(const Type *ty) { Ty = ty; } +public: + Value(const Type *Ty, ValueTy vty, const string &name = ""); + virtual ~Value(); + + inline const Type *getType() const { return Ty; } + inline ValueTy getValueType() const { return VTy; } + + inline bool hasName() const { return Name != ""; } + inline const string &getName() const { return Name; } + virtual void setName(const string &name) { Name = name; } + + + // replaceAllUsesWith - Go through the uses list for this definition and make + // each use point to "D" instead of "this". After this completes, 'this's + // use list should be empty. + // + void replaceAllUsesWith(Value *D); + + //---------------------------------------------------------------------- + // Methods for handling the list of uses of this DEF. + // + typedef list<User*>::iterator use_iterator; + typedef list<User*>::const_iterator use_const_iterator; + + inline bool use_size() const { return Uses.size(); } + inline bool use_empty() const { return Uses.empty(); } + inline use_iterator use_begin() { return Uses.begin(); } + inline use_const_iterator use_begin() const { return Uses.begin(); } + inline use_iterator use_end() { return Uses.end(); } + inline use_const_iterator use_end() const { return Uses.end(); } + + inline void use_push_back(User *I) { Uses.push_back(I); } + User *use_remove(use_iterator &I); + + inline void addUse(User *I) { Uses.push_back(I); } + void killUse(User *I); +}; + +// UseTy and it's friendly typedefs (Use) are here to make keeping the "use" +// list of a definition node up-to-date really easy. +// +template<class ValueSubclass> +class UseTy { + ValueSubclass *Val; + User *U; +public: + inline UseTy<ValueSubclass>(ValueSubclass *v, User *user) { + Val = v; U = user; + if (Val) Val->addUse(U); + } + + inline ~UseTy<ValueSubclass>() { if (Val) Val->killUse(U); } + + inline operator ValueSubclass *() const { return Val; } + + inline UseTy<ValueSubclass>(const UseTy<ValueSubclass> &user) { + Val = 0; + U = user.U; + operator=(user); + } + inline ValueSubclass *operator=(ValueSubclass *V) { + if (Val) Val->killUse(U); + Val = V; + if (V) V->addUse(U); + return V; + } + + inline ValueSubclass *operator->() { return Val; } + inline const ValueSubclass *operator->() const { return Val; } + + inline UseTy<ValueSubclass> &operator=(const UseTy<ValueSubclass> &user) { + if (Val) Val->killUse(U); + Val = user.Val; + Val->addUse(U); + return *this; + } +}; + +typedef UseTy<Value> Use; + +#endif diff --git a/include/llvm/ValueHolder.h b/include/llvm/ValueHolder.h new file mode 100644 index 0000000..318419f --- /dev/null +++ b/include/llvm/ValueHolder.h @@ -0,0 +1,86 @@ +//===-- llvm/ValueHolder.h - Class to hold multiple values -------*- C++ -*--=// +// +// This defines a class that is used as a fancy Definition container. It is +// special because it helps keep the symbol table of the container method up to +// date with the goings on inside of it. +// +// This is used to represent things like the instructions of a basic block and +// the arguments to a method. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_VALUEHOLDER_H +#define LLVM_VALUEHOLDER_H + +#include <vector> +class SymTabValue; + +// ItemParentType ItemParent - I call setParent() on all of my +// "ValueSubclass" items, and this is the value that I pass in. +// +template<class ValueSubclass, class ItemParentType> +class ValueHolder { + // TODO: Should I use a deque instead of a vector? + vector<ValueSubclass*> ValueList; + + ItemParentType *ItemParent; + SymTabValue *Parent; + + ValueHolder(const ValueHolder &V); // DO NOT IMPLEMENT +public: + inline ValueHolder(ItemParentType *IP, SymTabValue *parent = 0) { + assert(IP && "Item parent may not be null!"); + ItemParent = IP; + Parent = 0; + setParent(parent); + } + + inline ~ValueHolder() { + // The caller should have called delete_all first... + assert(empty() && "ValueHolder contains definitions!"); + assert(Parent == 0 && "Should have been unlinked from method!"); + } + + inline const SymTabValue *getParent() const { return Parent; } + inline SymTabValue *getParent() { return Parent; } + void setParent(SymTabValue *Parent); // Defined in ValueHolderImpl.h + + inline unsigned size() const { return ValueList.size(); } + inline bool empty() const { return ValueList.empty(); } + inline const ValueSubclass *front() const { return ValueList.front(); } + inline ValueSubclass *front() { return ValueList.front(); } + inline const ValueSubclass *back() const { return ValueList.back(); } + inline ValueSubclass *back() { return ValueList.back(); } + + //===--------------------------------------------------------------------===// + // sub-Definition iterator code + //===--------------------------------------------------------------------===// + // + typedef vector<ValueSubclass*>::iterator iterator; + typedef vector<ValueSubclass*>::const_iterator const_iterator; + + inline iterator begin() { return ValueList.begin(); } + inline const_iterator begin() const { return ValueList.begin(); } + inline iterator end() { return ValueList.end(); } + inline const_iterator end() const { return ValueList.end(); } + + void delete_all() { // Delete all removes and deletes all elements + // TODO: REMOVE FROM END OF VECTOR!!! + while (begin() != end()) { + iterator I = begin(); + delete remove(I); // Delete all instructions... + } + } + + // ValueHolder::remove(iterator &) this removes the element at the location + // specified by the iterator, and leaves the iterator pointing to the element + // that used to follow the element deleted. + // + ValueSubclass *remove(iterator &DI); // Defined in ValueHolderImpl.h + void remove(ValueSubclass *D); // Defined in ValueHolderImpl.h + + inline void push_front(ValueSubclass *Inst); // Defined in ValueHolderImpl.h + inline void push_back(ValueSubclass *Inst); // Defined in ValueHolderImpl.h +}; + +#endif diff --git a/include/llvm/iMemory.h b/include/llvm/iMemory.h new file mode 100644 index 0000000..077266d --- /dev/null +++ b/include/llvm/iMemory.h @@ -0,0 +1,140 @@ +//===-- llvm/iMemory.h - Memory Operator node definitions --------*- C++ -*--=// +// +// This file contains the declarations of all of the memory related operators. +// This includes: malloc, free, alloca, load, store, getfield, putfield +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IMEMORY_H +#define LLVM_IMEMORY_H + +#include "llvm/Instruction.h" +#include "llvm/DerivedTypes.h" +#include "llvm/ConstPoolVals.h" + +class ConstPoolType; + +class AllocationInst : public Instruction { +protected: + UseTy<ConstPoolType> TyVal; + Use ArraySize; +public: + AllocationInst(ConstPoolType *tyVal, Value *arrSize, unsigned iTy, + const string &Name = "") + : Instruction(tyVal->getValue(), iTy, Name), + TyVal(tyVal, this), ArraySize(arrSize, this) { + + // Make sure they didn't try to specify a size for an invalid type... + assert(arrSize == 0 || + (getType()->getValueType()->isArrayType() && + ((const ArrayType*)getType()->getValueType())->isUnsized()) && + "Trying to allocate something other than unsized array, with size!"); + + // Make sure that if a size is specified, that it is a uint! + assert(arrSize == 0 || arrSize->getType() == Type::UIntTy && + "Malloc SIZE is not a 'uint'!"); + } + inline ~AllocationInst() {} + + // getType - Overload to return most specific pointer type... + inline const PointerType *getType() const { + return (const PointerType*)Instruction::getType(); + } + + virtual Instruction *clone() const = 0; + + inline virtual void dropAllReferences() { TyVal = 0; ArraySize = 0; } + virtual bool setOperand(unsigned i, Value *Val) { + if (i == 0) { + assert(!Val || Val->getValueType() == Value::ConstantVal); + TyVal = (ConstPoolType*)Val; + return true; + } else if (i == 1) { + // Make sure they didn't try to specify a size for an invalid type... + assert(Val == 0 || + (getType()->getValueType()->isArrayType() && + ((const ArrayType*)getType()->getValueType())->isUnsized()) && + "Trying to allocate something other than unsized array, with size!"); + + // Make sure that if a size is specified, that it is a uint! + assert(Val == 0 || Val->getType() == Type::UIntTy && + "Malloc SIZE is not a 'uint'!"); + + ArraySize = Val; + return true; + } + return false; + } + + virtual unsigned getNumOperands() const { return 2; } + + virtual const Value *getOperand(unsigned i) const { + return i == 0 ? TyVal : (i == 1 ? ArraySize : 0); + } +}; + +class MallocInst : public AllocationInst { +public: + MallocInst(ConstPoolType *tyVal, Value *ArraySize = 0, + const string &Name = "") + : AllocationInst(tyVal, ArraySize, Instruction::Malloc, Name) {} + inline ~MallocInst() {} + + virtual Instruction *clone() const { + return new MallocInst(TyVal, ArraySize); + } + + virtual string getOpcode() const { return "malloc"; } +}; + +class AllocaInst : public AllocationInst { +public: + AllocaInst(ConstPoolType *tyVal, Value *ArraySize = 0, + const string &Name = "") + : AllocationInst(tyVal, ArraySize, Instruction::Alloca, Name) {} + inline ~AllocaInst() {} + + virtual Instruction *clone() const { + return new AllocaInst(TyVal, ArraySize); + } + + virtual string getOpcode() const { return "alloca"; } +}; + + + +class FreeInst : public Instruction { +protected: + Use Pointer; +public: + FreeInst(Value *Ptr, const string &Name = "") + : Instruction(Type::VoidTy, Instruction::Free, Name), + Pointer(Ptr, this) { + + assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!"); + } + inline ~FreeInst() {} + + virtual Instruction *clone() const { return new FreeInst(Pointer); } + + inline virtual void dropAllReferences() { Pointer = 0; } + + virtual bool setOperand(unsigned i, Value *Val) { + if (i == 0) { + assert(!Val || Val->getType()->isPointerType() && + "Can't free nonpointer!"); + Pointer = Val; + return true; + } + return false; + } + + virtual unsigned getNumOperands() const { return 1; } + virtual const Value *getOperand(unsigned i) const { + return i == 0 ? Pointer : 0; + } + + virtual string getOpcode() const { return "free"; } +}; + +#endif // LLVM_IMEMORY_H diff --git a/include/llvm/iOperators.h b/include/llvm/iOperators.h new file mode 100644 index 0000000..5a31b71 --- /dev/null +++ b/include/llvm/iOperators.h @@ -0,0 +1,48 @@ +//===-- llvm/iBinary.h - Binary Operator node definitions --------*- C++ -*--=// +// +// This file contains the declarations of all of the Binary Operator classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IBINARY_H +#define LLVM_IBINARY_H + +#include "llvm/InstrTypes.h" + +//===----------------------------------------------------------------------===// +// Classes to represent Binary operators +//===----------------------------------------------------------------------===// +// +// All of these classes are subclasses of the BinaryOperator class... +// + +class AddInst : public BinaryOperator { +public: + AddInst(Value *S1, Value *S2, const string &Name = "") + : BinaryOperator(Instruction::Add, S1, S2, Name) { + } + + virtual string getOpcode() const { return "add"; } +}; + + +class SubInst : public BinaryOperator { +public: + SubInst(Value *S1, Value *S2, const string &Name = "") + : BinaryOperator(Instruction::Sub, S1, S2, Name) { + } + + virtual string getOpcode() const { return "sub"; } +}; + + +class SetCondInst : public BinaryOperator { + BinaryOps OpType; +public: + SetCondInst(BinaryOps opType, Value *S1, Value *S2, + const string &Name = ""); + + virtual string getOpcode() const; +}; + +#endif diff --git a/include/llvm/iOther.h b/include/llvm/iOther.h new file mode 100644 index 0000000..4c06b4f --- /dev/null +++ b/include/llvm/iOther.h @@ -0,0 +1,116 @@ +//===-- llvm/iOther.h - "Other" instruction node definitions -----*- C++ -*--=// +// +// This file contains the declarations for instructions that fall into the +// grandios 'other' catagory... +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IOTHER_H +#define LLVM_IOTHER_H + +#include "llvm/InstrTypes.h" +#include "llvm/Method.h" +#include <vector> + +//===----------------------------------------------------------------------===// +// PHINode Class +//===----------------------------------------------------------------------===// + +// PHINode - The PHINode class is used to represent the magical mystical PHI +// node, that can not exist in nature, but can be synthesized in a computer +// scientist's overactive imagination. +// +// TODO: FIXME: This representation is not good enough. Consider the following +// code: +// BB0: %x = int %0 +// BB1: %y = int %1 +// BB2: %z = phi int %0, %1 - Can't tell where constants come from! +// +// TOFIX: Store pair<Use,BasicBlockUse> instead of just <Use> +// +class PHINode : public Instruction { + vector<Use> IncomingValues; + PHINode(const PHINode &PN); +public: + PHINode(const Type *Ty, const string &Name = ""); + inline ~PHINode() { dropAllReferences(); } + + virtual Instruction *clone() const { return new PHINode(*this); } + + // Implement all of the functionality required by User... + // + virtual void dropAllReferences(); + virtual const Value *getOperand(unsigned i) const { + return (i < IncomingValues.size()) ? IncomingValues[i] : 0; + } + inline Value *getOperand(unsigned i) { + return (Value*)((const PHINode*)this)->getOperand(i); + } + virtual unsigned getNumOperands() const { return IncomingValues.size(); } + virtual bool setOperand(unsigned i, Value *Val); + virtual string getOpcode() const { return "phi"; } + + void addIncoming(Value *D); +}; + + +//===----------------------------------------------------------------------===// +// MethodArgument Class +//===----------------------------------------------------------------------===// + +class MethodArgument : public Value { // Defined in the InstrType.cpp file + Method *Parent; + + friend class ValueHolder<MethodArgument,Method>; + inline void setParent(Method *parent) { Parent = parent; } + +public: + MethodArgument(const Type *Ty, const string &Name = "") + : Value(Ty, Value::MethodArgumentVal, Name) { + Parent = 0; + } + + // Specialize setName to handle symbol table majik... + virtual void setName(const string &name); + + inline const Method *getParent() const { return Parent; } + inline Method *getParent() { return Parent; } +}; + + +//===----------------------------------------------------------------------===// +// Classes to function calls and method invocations +//===----------------------------------------------------------------------===// + +class CallInst : public Instruction { + MethodUse M; + vector<Use> Params; + CallInst(const CallInst &CI); +public: + CallInst(Method *M, vector<Value*> ¶ms, const string &Name = ""); + inline ~CallInst() { dropAllReferences(); } + + virtual string getOpcode() const { return "call"; } + + virtual Instruction *clone() const { return new CallInst(*this); } + bool hasSideEffects() const { return true; } + + + const Method *getCalledMethod() const { return M; } + Method *getCalledMethod() { return M; } + + // Implement all of the functionality required by Instruction... + // + virtual void dropAllReferences(); + virtual const Value *getOperand(unsigned i) const { + return i == 0 ? M : ((i <= Params.size()) ? Params[i-1] : 0); + } + inline Value *getOperand(unsigned i) { + return (Value*)((const CallInst*)this)->getOperand(i); + } + virtual unsigned getNumOperands() const { return Params.size()+1; } + + virtual bool setOperand(unsigned i, Value *Val); +}; + +#endif diff --git a/include/llvm/iTerminators.h b/include/llvm/iTerminators.h new file mode 100644 index 0000000..0d1cde0 --- /dev/null +++ b/include/llvm/iTerminators.h @@ -0,0 +1,136 @@ +//===-- llvm/iTerminators.h - Termintator instruction nodes ------*- C++ -*--=// +// +// This file contains the declarations for all the subclasses of the +// Instruction class, which is itself defined in the Instruction.h file. In +// between these definitions and the Instruction class are classes that expose +// the SSA properties of each instruction, and that form the SSA graph. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ITERMINATORS_H +#define LLVM_ITERMINATORS_H + +#include "llvm/InstrTypes.h" +#include "llvm/BasicBlock.h" +#include "llvm/ConstPoolVals.h" + +//===----------------------------------------------------------------------===// +// Classes to represent Basic Block "Terminator" instructions +//===----------------------------------------------------------------------===// + + +//===--------------------------------------------------------------------------- +// ReturnInst - Return a value (possibly void), from a method. Execution does +// not continue in this method any longer. +// +class ReturnInst : public TerminatorInst { + Use Val; // Will be null if returning void... + ReturnInst(const ReturnInst &RI); +public: + ReturnInst(Value *value = 0); + inline ~ReturnInst() { dropAllReferences(); } + + virtual Instruction *clone() const { return new ReturnInst(*this); } + + virtual string getOpcode() const { return "ret"; } + + inline const Value *getReturnValue() const { return Val; } + inline Value *getReturnValue() { return Val; } + + virtual void dropAllReferences(); + virtual const Value *getOperand(unsigned i) const { + return (i == 0) ? Val : 0; + } + inline Value *getOperand(unsigned i) { return (i == 0) ? Val : 0; } + virtual bool setOperand(unsigned i, Value *Val); + virtual unsigned getNumOperands() const { return Val != 0; } + + // Additionally, they must provide a method to get at the successors of this + // terminator instruction. If 'idx' is out of range, a null pointer shall be + // returned. + // + virtual const BasicBlock *getSuccessor(unsigned idx) const { return 0; } + virtual unsigned getNumSuccessors() const { return 0; } +}; + + +//===--------------------------------------------------------------------------- +// BranchInst - Conditional or Unconditional Branch instruction. +// +class BranchInst : public TerminatorInst { + BasicBlockUse TrueDest, FalseDest; + Use Condition; + + BranchInst(const BranchInst &BI); +public: + // If cond = null, then is an unconditional br... + BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse = 0, Value *cond = 0); + inline ~BranchInst() { dropAllReferences(); } + + virtual Instruction *clone() const { return new BranchInst(*this); } + + virtual void dropAllReferences(); + + inline bool isUnconditional() const { + return Condition == 0 || !FalseDest; + } + + virtual string getOpcode() const { return "br"; } + + inline Value *getOperand(unsigned i) { + return (Value*)((const BranchInst *)this)->getOperand(i); + } + virtual const Value *getOperand(unsigned i) const; + virtual bool setOperand(unsigned i, Value *Val); + virtual unsigned getNumOperands() const { return isUnconditional() ? 1 : 3; } + + // Additionally, they must provide a method to get at the successors of this + // terminator instruction. If 'idx' is out of range, a null pointer shall be + // returned. + // + virtual const BasicBlock *getSuccessor(unsigned idx) const; + virtual unsigned getNumSuccessors() const { return 1+!isUnconditional(); } +}; + + +//===--------------------------------------------------------------------------- +// SwitchInst - Multiway switch +// +class SwitchInst : public TerminatorInst { +public: + typedef pair<ConstPoolUse, BasicBlockUse> dest_value; +private: + BasicBlockUse DefaultDest; + Use Val; + vector<dest_value> Destinations; + + SwitchInst(const SwitchInst &RI); +public: + typedef vector<dest_value>::iterator dest_iterator; + typedef vector<dest_value>::const_iterator dest_const_iterator; + + SwitchInst(Value *Value, BasicBlock *Default); + inline ~SwitchInst() { dropAllReferences(); } + + virtual Instruction *clone() const { return new SwitchInst(*this); } + + void dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest); + + virtual string getOpcode() const { return "switch"; } + inline Value *getOperand(unsigned i) { + return (Value*)((const SwitchInst*)this)->getOperand(i); + } + virtual const Value *getOperand(unsigned i) const; + virtual bool setOperand(unsigned i, Value *Val); + virtual unsigned getNumOperands() const; + virtual void dropAllReferences(); + + // Additionally, they must provide a method to get at the successors of this + // terminator instruction. If 'idx' is out of range, a null pointer shall be + // returned. + // + virtual const BasicBlock *getSuccessor(unsigned idx) const; + virtual unsigned getNumSuccessors() const { return 1+Destinations.size(); } +}; + +#endif diff --git a/include/llvm/iUnary.h b/include/llvm/iUnary.h new file mode 100644 index 0000000..ffe6c3f --- /dev/null +++ b/include/llvm/iUnary.h @@ -0,0 +1,19 @@ +//===-- llvm/iUnary.h - Unary Operator node definitions ----------*- C++ -*--=// +// +// This file contains the declarations of all of the Unary Operator classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IUNARY_H +#define LLVM_IUNARY_H + +#include "llvm/InstrTypes.h" + +//===----------------------------------------------------------------------===// +// Classes to represent Unary operators +//===----------------------------------------------------------------------===// +// +// All of these classes are subclasses of the UnaryOperator class... +// + +#endif |