| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
|
|
||
| LEVEL = ../.. | ||
|
|
||
| LIBRARYNAME = analysis | ||
|
|
||
| include $(LEVEL)/Makefile.common | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| //===-- llvm/Analysis/ModuleAnalyzer.cpp - Module analysis driver ----------==// | ||
| // | ||
| // 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. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/Analysis/ModuleAnalyzer.h" | ||
| #include "llvm/ConstantPool.h" | ||
| #include "llvm/Method.h" | ||
| #include "llvm/Module.h" | ||
| #include "llvm/BasicBlock.h" | ||
| #include "llvm/DerivedTypes.h" | ||
| #include "llvm/ConstPoolVals.h" | ||
| #include <map> | ||
|
|
||
| // processModule - Driver function to call all of my subclasses virtual methods. | ||
| // | ||
| bool ModuleAnalyzer::processModule(const Module *M) { | ||
| // Loop over the constant pool, process all of the constants... | ||
| if (processConstPool(M->getConstantPool(), false)) | ||
| return true; | ||
|
|
||
| return processMethods(M); | ||
| } | ||
|
|
||
| inline bool ModuleAnalyzer::handleType(set<const Type *> &TypeSet, | ||
| const Type *T) { | ||
| if (!T->isDerivedType()) return false; // Boring boring types... | ||
| if (TypeSet.count(T) != 0) return false; // Already found this type... | ||
| TypeSet.insert(T); // Add it to the set | ||
|
|
||
| // Recursively process interesting types... | ||
| switch (T->getPrimitiveID()) { | ||
| case Type::MethodTyID: { | ||
| const MethodType *MT = (const MethodType *)T; | ||
| if (handleType(TypeSet, MT->getReturnType())) return true; | ||
| const MethodType::ParamTypes &Params = MT->getParamTypes(); | ||
|
|
||
| for (MethodType::ParamTypes::const_iterator I = Params.begin(); | ||
| I != Params.end(); ++I) | ||
| if (handleType(TypeSet, *I)) return true; | ||
| break; | ||
| } | ||
|
|
||
| case Type::ArrayTyID: | ||
| if (handleType(TypeSet, ((const ArrayType *)T)->getElementType())) | ||
| return true; | ||
| break; | ||
|
|
||
| case Type::StructTyID: { | ||
| const StructType *ST = (const StructType*)T; | ||
| const StructType::ElementTypes &Elements = ST->getElementTypes(); | ||
| for (StructType::ElementTypes::const_iterator I = Elements.begin(); | ||
| I != Elements.end(); ++I) | ||
| if (handleType(TypeSet, *I)) return true; | ||
| break; | ||
| } | ||
|
|
||
| case Type::PointerTyID: | ||
| if (handleType(TypeSet, ((const PointerType *)T)->getValueType())) | ||
| return true; | ||
| break; | ||
|
|
||
| default: | ||
| cerr << "ModuleAnalyzer::handleType, type unknown: '" | ||
| << T->getName() << "'\n"; | ||
| break; | ||
| } | ||
|
|
||
| return processType(T); | ||
| } | ||
|
|
||
|
|
||
| bool ModuleAnalyzer::processConstPool(const ConstantPool &CP, bool isMethod) { | ||
| // TypeSet - Keep track of which types have already been processType'ed. We | ||
| // don't want to reprocess the same type more than once. | ||
| // | ||
| set<const Type *> TypeSet; | ||
|
|
||
| for (ConstantPool::plane_const_iterator PI = CP.begin(); | ||
| PI != CP.end(); ++PI) { | ||
| const ConstantPool::PlaneType &Plane = **PI; | ||
| if (Plane.empty()) continue; // Skip empty type planes... | ||
|
|
||
| if (processConstPoolPlane(CP, Plane, isMethod)) return true; | ||
|
|
||
| for (ConstantPool::PlaneType::const_iterator CI = Plane.begin(); | ||
| CI != Plane.end(); CI++) { | ||
| if ((*CI)->getType() == Type::TypeTy) | ||
| if (handleType(TypeSet, ((const ConstPoolType*)(*CI))->getValue())) | ||
| return true; | ||
| if (handleType(TypeSet, (*CI)->getType())) return true; | ||
|
|
||
| if (processConstant(*CI)) return true; | ||
| } | ||
| } | ||
|
|
||
| if (!isMethod) { | ||
| assert(CP.getParent()->getValueType() == Value::ModuleVal); | ||
| const Module *M = (const Module*)CP.getParent(); | ||
| // Process the method types after the constant pool... | ||
| for (Module::MethodListType::const_iterator I = M->getMethodList().begin(); | ||
| I != M->getMethodList().end(); I++) { | ||
| if (handleType(TypeSet, (*I)->getType())) return true; | ||
| if (visitMethod(*I)) return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool ModuleAnalyzer::processMethods(const Module *M) { | ||
| for (Module::MethodListType::const_iterator I = M->getMethodList().begin(); | ||
| I != M->getMethodList().end(); I++) | ||
| if (processMethod(*I)) return true; | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| bool ModuleAnalyzer::processMethod(const Method *M) { | ||
| // Loop over the arguments, processing them... | ||
| const Method::ArgumentListType &ArgList = M->getArgumentList(); | ||
| for (Method::ArgumentListType::const_iterator AI = ArgList.begin(); | ||
| AI != ArgList.end(); AI++) | ||
| if (processMethodArgument(*AI)) return true; | ||
|
|
||
| // Loop over the constant pool, adding the constants to the table... | ||
| processConstPool(M->getConstantPool(), true); | ||
|
|
||
| // Loop over all the basic blocks, in order... | ||
| Method::BasicBlocksType::const_iterator BBI = M->getBasicBlocks().begin(); | ||
| for (; BBI != M->getBasicBlocks().end(); BBI++) | ||
| if (processBasicBlock(*BBI)) return true; | ||
| return false; | ||
| } | ||
|
|
||
| bool ModuleAnalyzer::processBasicBlock(const BasicBlock *BB) { | ||
| // Process all of the instructions in the basic block | ||
| BasicBlock::InstListType::const_iterator Inst = BB->getInstList().begin(); | ||
| for (; Inst != BB->getInstList().end(); Inst++) { | ||
| if (preProcessInstruction(*Inst) || processInstruction(*Inst)) return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool ModuleAnalyzer::preProcessInstruction(const Instruction *I) { | ||
|
|
||
| return false; | ||
| } |