summaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp328
-rw-r--r--lib/VMCore/BasicBlock.cpp113
-rw-r--r--lib/VMCore/ConstantFold.cpp197
-rw-r--r--lib/VMCore/ConstantFold.h145
-rw-r--r--lib/VMCore/ConstantFolding.h145
-rw-r--r--lib/VMCore/ConstantPool.cpp434
-rw-r--r--lib/VMCore/Function.cpp75
-rw-r--r--lib/VMCore/InstrTypes.cpp66
-rw-r--r--lib/VMCore/Instruction.cpp61
-rw-r--r--lib/VMCore/Makefile7
-rw-r--r--lib/VMCore/Module.cpp42
-rw-r--r--lib/VMCore/SlotCalculator.cpp195
-rw-r--r--lib/VMCore/SymbolTable.cpp106
-rw-r--r--lib/VMCore/Type.cpp308
-rw-r--r--lib/VMCore/Value.cpp143
-rw-r--r--lib/VMCore/ValueHolderImpl.h85
-rw-r--r--lib/VMCore/Verifier.cpp94
-rw-r--r--lib/VMCore/iBranch.cpp69
-rw-r--r--lib/VMCore/iCall.cpp48
-rw-r--r--lib/VMCore/iOperators.cpp37
-rw-r--r--lib/VMCore/iReturn.cpp25
-rw-r--r--lib/VMCore/iSwitch.cpp81
22 files changed, 2804 insertions, 0 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
new file mode 100644
index 0000000..e23403b
--- /dev/null
+++ b/lib/VMCore/AsmWriter.cpp
@@ -0,0 +1,328 @@
+//===-- Writer.cpp - Library for Printing VM assembly files ------*- C++ -*--=//
+//
+// This library implements the functionality defined in llvm/Assembly/Writer.h
+//
+// This library uses the Analysis library to figure out offsets for
+// variables in the method tables...
+//
+// TODO: print out the type name instead of the full type if a particular type
+// is in the symbol table...
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Analysis/SlotCalculator.h"
+#include "llvm/Module.h"
+#include "llvm/Method.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/ConstPoolVals.h"
+#include "llvm/iOther.h"
+#include "llvm/iMemory.h"
+
+class AssemblyWriter : public ModuleAnalyzer {
+ ostream &Out;
+ SlotCalculator &Table;
+public:
+ inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) {
+ }
+
+ inline void write(const Module *M) { processModule(M); }
+ inline void write(const Method *M) { processMethod(M); }
+ inline void write(const BasicBlock *BB) { processBasicBlock(BB); }
+ inline void write(const Instruction *I) { processInstruction(I); }
+ inline void write(const ConstPoolVal *CPV) { processConstant(CPV); }
+
+protected:
+ virtual bool visitMethod(const Method *M);
+ virtual bool processConstPool(const ConstantPool &CP, bool isMethod);
+ virtual bool processConstant(const ConstPoolVal *CPV);
+ virtual bool processMethod(const Method *M);
+ virtual bool processMethodArgument(const MethodArgument *MA);
+ virtual bool processBasicBlock(const BasicBlock *BB);
+ virtual bool processInstruction(const Instruction *I);
+
+private :
+ void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
+};
+
+
+
+// visitMethod - This member is called after the above two steps, visting each
+// method, because they are effectively values that go into the constant pool.
+//
+bool AssemblyWriter::visitMethod(const Method *M) {
+ return false;
+}
+
+bool AssemblyWriter::processConstPool(const ConstantPool &CP, bool isMethod) {
+ // Done printing arguments...
+ if (isMethod) Out << ")\n";
+
+ ModuleAnalyzer::processConstPool(CP, isMethod);
+
+ if (isMethod)
+ Out << "begin";
+ else
+ Out << "implementation\n";
+ return false;
+}
+
+
+// processConstant - Print out a constant pool entry...
+//
+bool AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
+ Out << "\t";
+
+ // Print out name if it exists...
+ if (CPV->hasName())
+ Out << "%" << CPV->getName() << " = ";
+
+ // Print out the opcode...
+ Out << CPV->getType();
+
+ // Write the value out now...
+ writeOperand(CPV, false, false);
+
+ if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
+ int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
+ Out << "\t\t; <" << CPV->getType() << ">:";
+ if (Slot >= 0) Out << Slot;
+ else Out << "<badref>";
+ }
+
+ Out << endl;
+ return false;
+}
+
+// processMethod - Process all aspects of a method.
+//
+bool AssemblyWriter::processMethod(const Method *M) {
+ // Print out the return type and name...
+ Out << "\n" << M->getReturnType() << " \"" << M->getName() << "\"(";
+ Table.incorporateMethod(M);
+ ModuleAnalyzer::processMethod(M);
+ Table.purgeMethod();
+ Out << "end\n";
+ return false;
+}
+
+// processMethodArgument - This member is called for every argument that
+// is passed into the method. Simply print it out
+//
+bool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
+ // Insert commas as we go... the first arg doesn't get a comma
+ if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
+
+ // Output type...
+ Out << Arg->getType();
+
+ // Output name, if available...
+ if (Arg->hasName())
+ Out << " %" << Arg->getName();
+ else if (Table.getValSlot(Arg) < 0)
+ Out << "<badref>";
+
+ return false;
+}
+
+// processBasicBlock - This member is called for each basic block in a methd.
+//
+bool AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
+ if (BB->hasName()) { // Print out the label if it exists...
+ Out << "\n" << BB->getName() << ":\n";
+ } else {
+ int Slot = Table.getValSlot(BB);
+ Out << "\t\t\t\t; <label>:";
+ if (Slot >= 0)
+ Out << Slot << endl; // Extra newline seperates out label's
+ else
+ Out << "<badref>\n";
+ }
+
+ ModuleAnalyzer::processBasicBlock(BB);
+ return false;
+}
+
+// processInstruction - This member is called for each Instruction in a methd.
+//
+bool AssemblyWriter::processInstruction(const Instruction *I) {
+ Out << "\t";
+
+ // Print out name if it exists...
+ if (I && I->hasName())
+ Out << "%" << I->getName() << " = ";
+
+ // Print out the opcode...
+ Out << I->getOpcode();
+
+ // Print out the type of the operands...
+ const Value *Operand = I->getOperand(0);
+
+ // Special case conditional branches to swizzle the condition out to the front
+ if (I->getInstType() == Instruction::Br && I->getOperand(1)) {
+ writeOperand(I->getOperand(2), true);
+ Out << ",";
+ writeOperand(Operand, true);
+ Out << ",";
+ writeOperand(I->getOperand(1), true);
+
+ } else if (I->getInstType() == Instruction::Switch) {
+ // Special case switch statement to get formatting nice and correct...
+ writeOperand(Operand , true); Out << ",";
+ writeOperand(I->getOperand(1), true); Out << " [";
+
+ for (unsigned op = 2; (Operand = I->getOperand(op)); op += 2) {
+ Out << "\n\t\t";
+ writeOperand(Operand, true); Out << ",";
+ writeOperand(I->getOperand(op+1), true);
+ }
+ Out << "\n\t]";
+
+ } else if (I->getInstType() == Instruction::Ret && !Operand) {
+ Out << " void";
+ } else if (I->getInstType() == Instruction::Call) {
+ writeOperand(Operand, true);
+ Out << "(";
+ Operand = I->getOperand(1);
+ if (Operand) writeOperand(Operand, true);
+ for (unsigned op = 2; (Operand = I->getOperand(op)); ++op) {
+ Out << ",";
+ writeOperand(Operand, true);
+ }
+
+ Out << " )";
+ } else if (I->getInstType() == Instruction::Malloc ||
+ I->getInstType() == Instruction::Alloca) {
+ Out << " " << ((const PointerType*)((ConstPoolType*)Operand)
+ ->getValue())->getValueType();
+ if ((Operand = I->getOperand(1))) {
+ Out << ","; writeOperand(Operand, true);
+ }
+
+ } else if (Operand) { // Print the normal way...
+
+ // PrintAllTypes - Instructions who have operands of all the same type
+ // omit the type from all but the first operand. If the instruction has
+ // different type operands (for example br), then they are all printed.
+ bool PrintAllTypes = false;
+ const Type *TheType = Operand->getType();
+ unsigned i;
+
+ for (i = 1; (Operand = I->getOperand(i)); i++) {
+ if (Operand->getType() != TheType) {
+ PrintAllTypes = true; // We have differing types! Print them all!
+ break;
+ }
+ }
+
+ if (!PrintAllTypes)
+ Out << " " << I->getOperand(0)->getType();
+
+ for (unsigned i = 0; (Operand = I->getOperand(i)); i++) {
+ if (i) Out << ",";
+ writeOperand(Operand, PrintAllTypes);
+ }
+ }
+
+ // Print a little comment after the instruction indicating which slot it
+ // occupies.
+ //
+ if (!I->hasName() && I->getType() != Type::VoidTy) {
+ int Slot = Table.getValSlot(I); // Print out the def slot taken...
+ Out << "\t\t; <" << I->getType() << ">:";
+ if (Slot >= 0) Out << Slot;
+ else Out << "<badref>";
+
+ Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses
+ }
+
+ Out << endl;
+
+ return false;
+}
+
+
+void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
+ bool PrintName) {
+ if (PrintType)
+ Out << " " << Operand->getType();
+
+ if (Operand->hasName() && PrintName) {
+ Out << " %" << Operand->getName();
+ } else {
+ int Slot = Table.getValSlot(Operand);
+
+ if (Operand->getValueType() == Value::ConstantVal) {
+ Out << " " << ((ConstPoolVal*)Operand)->getStrValue();
+ } else {
+ if (Slot >= 0) Out << " %" << Slot;
+ else if (PrintName)
+ Out << "<badref>"; // Not embeded into a location?
+ }
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// External Interface declarations
+//===----------------------------------------------------------------------===//
+
+
+
+void WriteToAssembly(const Module *M, ostream &o) {
+ if (M == 0) { o << "<null> module\n"; return; }
+ SlotCalculator SlotTable(M, true);
+ AssemblyWriter W(o, SlotTable);
+
+ W.write(M);
+}
+
+void WriteToAssembly(const Method *M, ostream &o) {
+ if (M == 0) { o << "<null> method\n"; return; }
+ SlotCalculator SlotTable(M->getParent(), true);
+ AssemblyWriter W(o, SlotTable);
+
+ W.write(M);
+}
+
+
+void WriteToAssembly(const BasicBlock *BB, ostream &o) {
+ if (BB == 0) { o << "<null> basic block\n"; return; }
+
+ SlotCalculator SlotTable(BB->getParent(), true);
+ AssemblyWriter W(o, SlotTable);
+
+ W.write(BB);
+}
+
+void WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
+ if (CPV == 0) { o << "<null> constant pool value\n"; return; }
+
+ SlotCalculator *SlotTable;
+
+ // A Constant pool value may have a parent that is either a method or a
+ // module. Untangle this now...
+ //
+ if (CPV->getParent() == 0 ||
+ CPV->getParent()->getValueType() == Value::MethodVal) {
+ SlotTable = new SlotCalculator((Method*)CPV->getParent(), true);
+ } else {
+ assert(CPV->getParent()->getValueType() == Value::ModuleVal);
+ SlotTable = new SlotCalculator((Module*)CPV->getParent(), true);
+ }
+
+ AssemblyWriter W(o, *SlotTable);
+ W.write(CPV);
+
+ delete SlotTable;
+}
+
+void WriteToAssembly(const Instruction *I, ostream &o) {
+ if (I == 0) { o << "<null> instruction\n"; return; }
+
+ SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0,
+ true);
+ AssemblyWriter W(o, SlotTable);
+
+ W.write(I);
+}
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp
new file mode 100644
index 0000000..f60bd46
--- /dev/null
+++ b/lib/VMCore/BasicBlock.cpp
@@ -0,0 +1,113 @@
+//===-- BasicBlock.cpp - Implement BasicBlock related functions --*- C++ -*--=//
+//
+// This file implements the Method class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ValueHolderImpl.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/iTerminators.h"
+#include "llvm/Module.h"
+#include "llvm/Method.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/Type.h"
+
+// Instantiate Templates - This ugliness is the price we have to pay
+// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
+//
+template class ValueHolder<Instruction, BasicBlock>;
+
+BasicBlock::BasicBlock(const string &name, Method *parent)
+ : Value(Type::LabelTy, Value::BasicBlockVal, name), InstList(this, 0) {
+
+ if (parent)
+ parent->getBasicBlocks().push_back(this);
+}
+
+BasicBlock::~BasicBlock() {
+ dropAllReferences();
+ InstList.delete_all();
+}
+
+// Specialize setName to take care of symbol table majik
+void BasicBlock::setName(const string &name) {
+ Method *P;
+ if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (P && hasName()) P->getSymbolTable()->insert(this);
+}
+
+void BasicBlock::setParent(Method *parent) {
+ if (getParent() && hasName())
+ getParent()->getSymbolTable()->remove(this);
+
+ InstList.setParent(parent);
+
+ if (getParent() && hasName())
+ getParent()->getSymbolTableSure()->insert(this);
+}
+
+TerminatorInst *BasicBlock::getTerminator() {
+ if (InstList.empty()) return 0;
+ Instruction *T = InstList.back();
+ if (T->isTerminator()) return (TerminatorInst*)T;
+ return 0;
+}
+
+const TerminatorInst *const BasicBlock::getTerminator() const {
+ if (InstList.empty()) return 0;
+ const Instruction *T = InstList.back();
+ if (T->isTerminator()) return (TerminatorInst*)T;
+ return 0;
+}
+
+void BasicBlock::dropAllReferences() {
+ for_each(InstList.begin(), InstList.end(),
+ std::mem_fun(&Instruction::dropAllReferences));
+}
+
+// hasConstantPoolReferences() - This predicate is true if there is a
+// reference to this basic block in the constant pool for this method. For
+// example, if a block is reached through a switch table, that table resides
+// in the constant pool, and the basic block is reference from it.
+//
+bool BasicBlock::hasConstantPoolReferences() const {
+ for (use_const_iterator I = use_begin(), E = use_end(); I != E; ++I)
+ if ((*I)->getValueType() == ConstantVal)
+ return true;
+
+ return false;
+}
+
+
+// splitBasicBlock - This splits a basic block into two at the specified
+// instruction. Note that all instructions BEFORE the specified iterator stay
+// as part of the original basic block, an unconditional branch is added to
+// the new BB, and the rest of the instructions in the BB are moved to the new
+// BB, including the old terminator. This invalidates the iterator.
+//
+// Note that this only works on well formed basic blocks (must have a
+// terminator), and 'I' must not be the end of instruction list (which would
+// cause a degenerate basic block to be formed, having a terminator inside of
+// the basic block).
+//
+BasicBlock *BasicBlock::splitBasicBlock(InstListType::iterator I) {
+ assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
+ assert(I != InstList.end() &&
+ "Trying to get me to create degenerate basic block!");
+
+ BasicBlock *New = new BasicBlock("", getParent());
+
+ // Go from the end of the basic block through to the iterator pointer, moving
+ // to the new basic block...
+ Instruction *Inst = 0;
+ do {
+ InstListType::iterator EndIt = InstList.end();
+ Inst = InstList.remove(--EndIt); // Remove from end
+ New->InstList.push_front(Inst); // Add to front
+ } while (Inst != *I); // Loop until we move the specified instruction.
+
+ // Add a branch instruction to the newly formed basic block.
+ InstList.push_back(new BranchInst(New));
+ return New;
+}
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
new file mode 100644
index 0000000..438ea4b
--- /dev/null
+++ b/lib/VMCore/ConstantFold.cpp
@@ -0,0 +1,197 @@
+//===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===//
+//
+// This file implements the various intrinsic operations, on constant values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Opt/ConstantHandling.h"
+
+//===----------------------------------------------------------------------===//
+// TemplateRules Class
+//===----------------------------------------------------------------------===//
+//
+// TemplateRules - Implement a subclass of ConstRules that provides all
+// operations as noops. All other rules classes inherit from this class so
+// that if functionality is needed in the future, it can simply be added here
+// and to ConstRules without changing anything else...
+//
+// This class also provides subclasses with typesafe implementations of methods
+// so that don't have to do type casting.
+//
+template<class ArgType, class SubClassName>
+class TemplateRules : public ConstRules {
+
+ //===--------------------------------------------------------------------===//
+ // Redirecting functions that cast to the appropriate types
+ //===--------------------------------------------------------------------===//
+
+ virtual ConstPoolVal *neg(const ConstPoolVal *V) const {
+ return SubClassName::Neg((const ArgType *)V);
+ }
+
+ virtual ConstPoolVal *not(const ConstPoolVal *V) const {
+ return SubClassName::Not((const ArgType *)V);
+ }
+
+
+ virtual ConstPoolVal *add(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const {
+ return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
+ }
+
+ virtual ConstPoolVal *sub(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const {
+ return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
+ }
+
+ virtual ConstPoolBool *lessthan(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const {
+ return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Default "noop" implementations
+ //===--------------------------------------------------------------------===//
+
+ inline static ConstPoolVal *Neg(const ArgType *V) { return 0; }
+ inline static ConstPoolVal *Not(const ArgType *V) { return 0; }
+
+ inline static ConstPoolVal *Add(const ArgType *V1, const ArgType *V2) {
+ return 0;
+ }
+
+ inline static ConstPoolVal *Sub(const ArgType *V1, const ArgType *V2) {
+ return 0;
+ }
+
+ inline static ConstPoolBool *LessThan(const ArgType *V1, const ArgType *V2) {
+ return 0;
+ }
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// EmptyRules Class
+//===----------------------------------------------------------------------===//
+//
+// EmptyRules provides a concrete base class of ConstRules that does nothing
+//
+static // EmptyInst is static
+struct EmptyRules : public TemplateRules<ConstPoolVal, EmptyRules> {
+} EmptyInst;
+
+
+
+//===----------------------------------------------------------------------===//
+// BoolRules Class
+//===----------------------------------------------------------------------===//
+//
+// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
+//
+static // BoolTyInst is static...
+struct BoolRules : public TemplateRules<ConstPoolBool, BoolRules> {
+
+ inline static ConstPoolVal *Not(const ConstPoolBool *V) {
+ return new ConstPoolBool(!V->getValue());
+ }
+
+ inline static ConstPoolVal *Or(const ConstPoolBool *V1,
+ const ConstPoolBool *V2) {
+ bool Result = V1->getValue() | V2->getValue();
+ return new ConstPoolBool(Result);
+ }
+
+ inline static ConstPoolVal *And(const ConstPoolBool *V1,
+ const ConstPoolBool *V2) {
+ bool Result = V1->getValue() & V2->getValue();
+ return new ConstPoolBool(Result);
+ }
+} BoolTyInst;
+
+
+//===----------------------------------------------------------------------===//
+// DirectRules Class
+//===----------------------------------------------------------------------===//
+//
+// DirectRules provides a concrete base classes of ConstRules for a variety of
+// different types. This allows the C++ compiler to automatically generate our
+// constant handling operations in a typesafe and accurate manner.
+//
+template<class ConstPoolClass, class BuiltinType, const Type **Ty>
+struct DirectRules
+ : public TemplateRules<ConstPoolClass,
+ DirectRules<ConstPoolClass, BuiltinType, Ty> > {
+
+ inline static ConstPoolVal *Neg(const ConstPoolClass *V) {
+ return new ConstPoolClass(*Ty, -(BuiltinType)V->getValue());;
+ }
+ inline static ConstPoolVal *Not(const ConstPoolClass *V) {
+ return new ConstPoolClass(*Ty, !(BuiltinType)V->getValue());;
+ }
+
+ inline static ConstPoolVal *Add(const ConstPoolClass *V1,
+ const ConstPoolClass *V2) {
+ BuiltinType Result = (BuiltinType)V1->getValue() +
+ (BuiltinType)V2->getValue();
+ return new ConstPoolClass(*Ty, Result);
+ }
+
+ inline static ConstPoolVal *Sub(const ConstPoolClass *V1,
+ const ConstPoolClass *V2) {
+ BuiltinType Result = (BuiltinType)V1->getValue() -
+ (BuiltinType)V2->getValue();
+ return new ConstPoolClass(*Ty, Result);
+ }
+
+ inline static ConstPoolBool *LessThan(const ConstPoolClass *V1,
+ const ConstPoolClass *V2) {
+ bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
+ return new ConstPoolBool(Result);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// DirectRules Subclasses
+//===----------------------------------------------------------------------===//
+//
+// Given the DirectRules class we can now implement lots of types with little
+// code. Thank goodness C++ compilers are great at stomping out layers of
+// templates... can you imagine having to do this all by hand? (/me is lazy :)
+//
+static DirectRules<ConstPoolSInt, signed char , &Type::SByteTy> SByteTyInst;
+static DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy> UByteTyInst;
+static DirectRules<ConstPoolSInt, signed short, &Type::ShortTy> ShortTyInst;
+static DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy> UShortTyInst;
+static DirectRules<ConstPoolSInt, signed int , &Type::IntTy> IntTyInst;
+static DirectRules<ConstPoolUInt, unsigned int , &Type::UIntTy> UIntTyInst;
+static DirectRules<ConstPoolSInt, int64_t , &Type::LongTy> LongTyInst;
+static DirectRules<ConstPoolUInt, uint64_t , &Type::ULongTy> ULongTyInst;
+static DirectRules<ConstPoolFP , float , &Type::FloatTy> FloatTyInst;
+static DirectRules<ConstPoolFP , double , &Type::DoubleTy> DoubleTyInst;
+
+
+// ConstRules::find - Return the constant rules that take care of the specified
+// type. Note that this is cached in the Type value itself, so switch statement
+// is only hit at most once per type.
+//
+const ConstRules *ConstRules::find(const Type *Ty) {
+ const ConstRules *Result;
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID: Result = &BoolTyInst; break;
+ case Type::SByteTyID: Result = &SByteTyInst; break;
+ case Type::UByteTyID: Result = &UByteTyInst; break;
+ case Type::ShortTyID: Result = &ShortTyInst; break;
+ case Type::UShortTyID: Result = &UShortTyInst; break;
+ case Type::IntTyID: Result = &IntTyInst; break;
+ case Type::UIntTyID: Result = &UIntTyInst; break;
+ case Type::LongTyID: Result = &LongTyInst; break;
+ case Type::ULongTyID: Result = &ULongTyInst; break;
+ case Type::FloatTyID: Result = &FloatTyInst; break;
+ case Type::DoubleTyID: Result = &DoubleTyInst; break;
+ default: Result = &EmptyInst; break;
+ }
+
+ Ty->setConstRules(Result); // Cache the value for future short circuiting!
+ return Result;
+}
diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h
new file mode 100644
index 0000000..3227e39
--- /dev/null
+++ b/lib/VMCore/ConstantFold.h
@@ -0,0 +1,145 @@
+//===-- ConstantHandling.h - Stuff for manipulating constants ----*- C++ -*--=//
+//
+// This file contains the declarations of some cool operators that allow you
+// to do natural things with constant pool values.
+//
+// Unfortunately we can't overload operators on pointer types (like this:)
+//
+// inline bool operator==(const ConstPoolVal *V1, const ConstPoolVal *V2)
+//
+// so we must make due with references, even though it leads to some butt ugly
+// looking code downstream. *sigh* (ex: ConstPoolVal *Result = *V1 + *v2; )
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: These operators return pointers to newly 'new'd objects. You MUST
+// make sure to free them if you don't want them hanging around. Also,
+// note that these may return a null object if I don't know how to
+// perform those operations on the specified constant types.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation notes:
+// This library is implemented this way for a reason: In most cases, we do
+// not want to have to link the constant mucking code into an executable.
+// We do, however want to tie some of this into the main type system, as an
+// optional component. By using a mutable cache member in the Type class, we
+// get exactly the kind of behavior we want.
+//
+// In the end, we get performance almost exactly the same as having a virtual
+// function dispatch, but we don't have to put our virtual functions into the
+// "Type" class, and we can implement functionality with templates. Good deal.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPT_CONSTANTHANDLING_H
+#define LLVM_OPT_CONSTANTHANDLING_H
+
+#include "llvm/ConstPoolVals.h"
+#include "llvm/Type.h"
+
+//===----------------------------------------------------------------------===//
+// Implement == directly...
+//===----------------------------------------------------------------------===//
+
+inline ConstPoolBool *operator==(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return new ConstPoolBool(V1.equals(&V2));
+}
+
+//===----------------------------------------------------------------------===//
+// Implement all other operators indirectly through TypeRules system
+//===----------------------------------------------------------------------===//
+
+class ConstRules {
+protected:
+ inline ConstRules() {} // Can only be subclassed...
+public:
+ // Unary Operators...
+ virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0;
+ virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0;
+
+ // Binary Operators...
+ virtual ConstPoolVal *add(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+ virtual ConstPoolVal *sub(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+
+ virtual ConstPoolBool *lessthan(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+
+ // ConstRules::get - A type will cache its own type rules if one is needed...
+ // we just want to make sure to hit the cache instead of doing it indirectly,
+ // if possible...
+ //
+ static inline const ConstRules *get(const ConstPoolVal &V) {
+ const ConstRules *Result = V.getType()->getConstRules();
+ return Result ? Result : find(V.getType());
+ }
+private :
+ static const ConstRules *find(const Type *Ty);
+
+ ConstRules(const ConstRules &); // Do not implement
+ ConstRules &operator=(const ConstRules &); // Do not implement
+};
+
+
+inline ConstPoolVal *operator-(const ConstPoolVal &V) {
+ return ConstRules::get(V)->neg(&V);
+}
+
+inline ConstPoolVal *operator!(const ConstPoolVal &V) {
+ return ConstRules::get(V)->not(&V);
+}
+
+
+
+inline ConstPoolVal *operator+(const ConstPoolVal &V1, const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->add(&V1, &V2);
+}
+
+inline ConstPoolVal *operator-(const ConstPoolVal &V1, const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->sub(&V1, &V2);
+}
+
+inline ConstPoolBool *operator<(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->lessthan(&V1, &V2);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Implement 'derived' operators based on what we already have...
+//===----------------------------------------------------------------------===//
+
+inline ConstPoolBool *operator>(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ return V2 < V1;
+}
+
+inline ConstPoolBool *operator!=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 == V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 == V2)
+}
+
+inline ConstPoolBool *operator>=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 < V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 < V2)
+}
+
+inline ConstPoolBool *operator<=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 > V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 > V2)
+}
+
+#endif
diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h
new file mode 100644
index 0000000..3227e39
--- /dev/null
+++ b/lib/VMCore/ConstantFolding.h
@@ -0,0 +1,145 @@
+//===-- ConstantHandling.h - Stuff for manipulating constants ----*- C++ -*--=//
+//
+// This file contains the declarations of some cool operators that allow you
+// to do natural things with constant pool values.
+//
+// Unfortunately we can't overload operators on pointer types (like this:)
+//
+// inline bool operator==(const ConstPoolVal *V1, const ConstPoolVal *V2)
+//
+// so we must make due with references, even though it leads to some butt ugly
+// looking code downstream. *sigh* (ex: ConstPoolVal *Result = *V1 + *v2; )
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: These operators return pointers to newly 'new'd objects. You MUST
+// make sure to free them if you don't want them hanging around. Also,
+// note that these may return a null object if I don't know how to
+// perform those operations on the specified constant types.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation notes:
+// This library is implemented this way for a reason: In most cases, we do
+// not want to have to link the constant mucking code into an executable.
+// We do, however want to tie some of this into the main type system, as an
+// optional component. By using a mutable cache member in the Type class, we
+// get exactly the kind of behavior we want.
+//
+// In the end, we get performance almost exactly the same as having a virtual
+// function dispatch, but we don't have to put our virtual functions into the
+// "Type" class, and we can implement functionality with templates. Good deal.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPT_CONSTANTHANDLING_H
+#define LLVM_OPT_CONSTANTHANDLING_H
+
+#include "llvm/ConstPoolVals.h"
+#include "llvm/Type.h"
+
+//===----------------------------------------------------------------------===//
+// Implement == directly...
+//===----------------------------------------------------------------------===//
+
+inline ConstPoolBool *operator==(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return new ConstPoolBool(V1.equals(&V2));
+}
+
+//===----------------------------------------------------------------------===//
+// Implement all other operators indirectly through TypeRules system
+//===----------------------------------------------------------------------===//
+
+class ConstRules {
+protected:
+ inline ConstRules() {} // Can only be subclassed...
+public:
+ // Unary Operators...
+ virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0;
+ virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0;
+
+ // Binary Operators...
+ virtual ConstPoolVal *add(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+ virtual ConstPoolVal *sub(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+
+ virtual ConstPoolBool *lessthan(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
+
+ // ConstRules::get - A type will cache its own type rules if one is needed...
+ // we just want to make sure to hit the cache instead of doing it indirectly,
+ // if possible...
+ //
+ static inline const ConstRules *get(const ConstPoolVal &V) {
+ const ConstRules *Result = V.getType()->getConstRules();
+ return Result ? Result : find(V.getType());
+ }
+private :
+ static const ConstRules *find(const Type *Ty);
+
+ ConstRules(const ConstRules &); // Do not implement
+ ConstRules &operator=(const ConstRules &); // Do not implement
+};
+
+
+inline ConstPoolVal *operator-(const ConstPoolVal &V) {
+ return ConstRules::get(V)->neg(&V);
+}
+
+inline ConstPoolVal *operator!(const ConstPoolVal &V) {
+ return ConstRules::get(V)->not(&V);
+}
+
+
+
+inline ConstPoolVal *operator+(const ConstPoolVal &V1, const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->add(&V1, &V2);
+}
+
+inline ConstPoolVal *operator-(const ConstPoolVal &V1, const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->sub(&V1, &V2);
+}
+
+inline ConstPoolBool *operator<(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->lessthan(&V1, &V2);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Implement 'derived' operators based on what we already have...
+//===----------------------------------------------------------------------===//
+
+inline ConstPoolBool *operator>(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ return V2 < V1;
+}
+
+inline ConstPoolBool *operator!=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 == V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 == V2)
+}
+
+inline ConstPoolBool *operator>=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 < V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 < V2)
+}
+
+inline ConstPoolBool *operator<=(const ConstPoolVal &V1,
+ const ConstPoolVal &V2) {
+ ConstPoolBool *Result = V1 > V2;
+ Result->setValue(!Result->getValue()); // Invert value
+ return Result; // !(V1 > V2)
+}
+
+#endif
diff --git a/lib/VMCore/ConstantPool.cpp b/lib/VMCore/ConstantPool.cpp
new file mode 100644
index 0000000..d624c8d
--- /dev/null
+++ b/lib/VMCore/ConstantPool.cpp
@@ -0,0 +1,434 @@
+//===-- iConstPool.cpp - Implement ConstPool instructions --------*- C++ -*--=//
+//
+// This file implements the ConstPool* classes...
+//
+//===----------------------------------------------------------------------===//
+
+#define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends...
+#include "llvm/ConstPoolVals.h"
+#include "llvm/ConstantPool.h"
+#include "llvm/Tools/StringExtras.h" // itostr
+#include "llvm/DerivedTypes.h"
+#include "llvm/SymbolTable.h"
+#include <algorithm>
+#include <assert.h>
+
+//===----------------------------------------------------------------------===//
+// ConstantPool Class
+//===----------------------------------------------------------------------===//
+
+void ConstantPool::setParent(SymTabValue *STV) {
+ Parent = STV;
+ for (unsigned i = 0; i < Planes.size(); i++)
+ Planes[i]->setParent(Parent);
+}
+
+// Constant getPlane - Returns true if the type plane does not exist, otherwise
+// updates the pointer to point to the correct plane.
+//
+bool ConstantPool::getPlane(const Type *T, const PlaneType *&Plane) const {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) return true;
+ Plane = Planes[Ty];
+ return false;
+}
+
+// Constant getPlane - Returns true if the type plane does not exist, otherwise
+// updates the pointer to point to the correct plane.
+//
+bool ConstantPool::getPlane(const Type *T, PlaneType *&Plane) {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) return true;
+ Plane = Planes[Ty];
+ return false;
+}
+
+void ConstantPool::resize(unsigned size) {
+ unsigned oldSize = Planes.size();
+ Planes.resize(size, 0);
+ while (oldSize < size)
+ Planes[oldSize++] = new PlaneType(Parent, Parent);
+}
+
+ConstantPool::PlaneType &ConstantPool::getPlane(const Type *T) {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) resize(Ty+1);
+ return *Planes[Ty];
+}
+
+// insert - Add constant into the symbol table...
+void ConstantPool::insert(ConstPoolVal *N) {
+ unsigned Ty = N->getType()->getUniqueID();
+ if (Ty >= Planes.size()) resize(Ty+1);
+ Planes[Ty]->push_back(N);
+}
+
+bool ConstantPool::remove(ConstPoolVal *N) {
+ unsigned Ty = N->getType()->getUniqueID();
+ if (Ty >= Planes.size()) return true; // Doesn't contain any of that type
+
+ PlaneType::iterator I = ::find(Planes[Ty]->begin(), Planes[Ty]->end(), N);
+ if (I == Planes[Ty]->end()) return true;
+ Planes[Ty]->remove(I);
+ return false;
+}
+
+void ConstantPool::delete_all() {
+ dropAllReferences();
+ for (unsigned i = 0; i < Planes.size(); i++) {
+ Planes[i]->delete_all();
+ Planes[i]->setParent(0);
+ delete Planes[i];
+ }
+ Planes.clear();
+}
+
+void ConstantPool::dropAllReferences() {
+ for (unsigned i = 0; i < Planes.size(); i++)
+ for (PlaneType::iterator I = Planes[i]->begin();
+ I != Planes[i]->end(); I++)
+ (*I)->dropAllReferences();
+}
+
+struct EqualsConstant {
+ const ConstPoolVal *v;
+ inline EqualsConstant(const ConstPoolVal *V) { v = V; }
+ inline bool operator()(const ConstPoolVal *V) const {
+ return v->equals(V);
+ }
+};
+
+
+ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) {
+ const PlaneType *P;
+ if (getPlane(V->getType(), P)) return 0;
+ PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
+ EqualsConstant(V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+const ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) const {
+ const PlaneType *P;
+ if (getPlane(V->getType(), P)) return 0;
+ PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
+ EqualsConstant(V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+ConstPoolVal *ConstantPool::find(const Type *Ty) {
+ const PlaneType *P;
+ if (getPlane(Type::TypeTy, P)) return 0;
+
+ // TODO: This is kinda silly
+ ConstPoolType V(Ty);
+
+ PlaneType::const_iterator PI =
+ find_if(P->begin(), P->end(), EqualsConstant(&V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+const ConstPoolVal *ConstantPool::find(const Type *Ty) const {
+ const PlaneType *P;
+ if (getPlane(Type::TypeTy, P)) return 0;
+
+ // TODO: This is kinda silly
+ ConstPoolType V(Ty);
+
+ PlaneType::const_iterator PI =
+ find_if(P->begin(), P->end(), EqualsConstant(&V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+//===----------------------------------------------------------------------===//
+// ConstPoolVal Class
+//===----------------------------------------------------------------------===//
+
+// Specialize setName to take care of symbol table majik
+void ConstPoolVal::setName(const string &name) {
+ SymTabValue *P;
+ if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (P && hasName()) P->getSymbolTable()->insert(this);
+}
+
+// Static constructor to create a '0' constant of arbitrary type...
+ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID: return new ConstPoolBool(false);
+ case Type::SByteTyID:
+ case Type::ShortTyID:
+ case Type::IntTyID:
+ case Type::LongTyID: return new ConstPoolSInt(Ty, 0);
+
+ case Type::UByteTyID:
+ case Type::UShortTyID:
+ case Type::UIntTyID:
+ case Type::ULongTyID: return new ConstPoolUInt(Ty, 0);
+
+ case Type::FloatTyID:
+ case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
+ default:
+ return 0;
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// ConstPoolXXX Classes
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Normal Constructors
+
+ConstPoolBool::ConstPoolBool(bool V, const string &Name = "")
+ : ConstPoolVal(Type::BoolTy, Name) {
+ Val = V;
+}
+
+ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolType::ConstPoolType(const Type *V, const string &Name)
+ : ConstPoolVal(Type::TypeTy, Name), Val(V) {
+}
+
+ConstPoolArray::ConstPoolArray(const ArrayType *T,
+ vector<ConstPoolVal*> &V,
+ const string &Name)
+ : ConstPoolVal(T, Name) {
+ for (unsigned i = 0; i < V.size(); i++) {
+ assert(V[i]->getType() == T->getElementType());
+ Val.push_back(ConstPoolUse(V[i], this));
+ }
+}
+
+ConstPoolStruct::ConstPoolStruct(const StructType *T,
+ vector<ConstPoolVal*> &V,
+ const string &Name)
+ : ConstPoolVal(T, Name) {
+ const StructType::ElementTypes &ETypes = T->getElementTypes();
+
+ for (unsigned i = 0; i < V.size(); i++) {
+ assert(V[i]->getType() == ETypes[i]);
+ Val.push_back(ConstPoolUse(V[i], this));
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Copy Constructors
+
+ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
+ : ConstPoolVal(Type::BoolTy) {
+ Val = CPB.Val;
+}
+
+ConstPoolSInt::ConstPoolSInt(const ConstPoolSInt &CPSI)
+ : ConstPoolVal(CPSI.getType()) {
+ Val = CPSI.Val;
+}
+
+ConstPoolUInt::ConstPoolUInt(const ConstPoolUInt &CPUI)
+ : ConstPoolVal(CPUI.getType()) {
+ Val = CPUI.Val;
+}
+
+ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
+ : ConstPoolVal(CPFP.getType()) {
+ Val = CPFP.Val;
+}
+
+ConstPoolType::ConstPoolType(const ConstPoolType &CPT)
+ : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
+}
+
+ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
+ : ConstPoolVal(CPA.getType()) {
+ for (unsigned i = 0; i < CPA.Val.size(); i++)
+ Val.push_back(ConstPoolUse((ConstPoolVal*)CPA.Val[i], this));
+}
+
+ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
+ : ConstPoolVal(CPS.getType()) {
+ for (unsigned i = 0; i < CPS.Val.size(); i++)
+ Val.push_back(ConstPoolUse((ConstPoolVal*)CPS.Val[i], this));
+}
+
+//===----------------------------------------------------------------------===//
+// getStrValue implementations
+
+string ConstPoolBool::getStrValue() const {
+ if (Val)
+ return "true";
+ else
+ return "false";
+}
+
+string ConstPoolSInt::getStrValue() const {
+ return itostr(Val);
+}
+
+string ConstPoolUInt::getStrValue() const {
+ return utostr(Val);
+}
+
+string ConstPoolFP::getStrValue() const {
+ assert(0 && "FP Constants Not implemented yet!!!!!!!!!!!");
+ return "% FP Constants NI!" /* + dtostr(Val)*/;
+}
+
+string ConstPoolType::getStrValue() const {
+ return Val->getName();
+}
+
+string ConstPoolArray::getStrValue() const {
+ string Result = "[";
+ if (Val.size()) {
+ Result += " " + Val[0]->getType()->getName() +
+ " " + Val[0]->getStrValue();
+ for (unsigned i = 1; i < Val.size(); i++)
+ Result += ", " + Val[i]->getType()->getName() +
+ " " + Val[i]->getStrValue();
+ }
+
+ return Result + " ]";
+}
+
+string ConstPoolStruct::getStrValue() const {
+ string Result = "{";
+ if (Val.size()) {
+ Result += " " + Val[0]->getType()->getName() +
+ " " + Val[0]->getStrValue();
+ for (unsigned i = 1; i < Val.size(); i++)
+ Result += ", " + Val[i]->getType()->getName() +
+ " " + Val[i]->getStrValue();
+ }
+
+ return Result + " }";
+}
+
+//===----------------------------------------------------------------------===//
+// equals implementations
+
+bool ConstPoolBool::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolBool*)V)->getValue() == Val;
+}
+
+bool ConstPoolSInt::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolSInt*)V)->getValue() == Val;
+}
+
+bool ConstPoolUInt::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolUInt*)V)->getValue() == Val;
+}
+
+bool ConstPoolFP::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolFP*)V)->getValue() == Val;
+}
+
+bool ConstPoolType::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolType*)V)->getValue() == Val;
+}
+
+bool ConstPoolArray::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ ConstPoolArray *AV = (ConstPoolArray*)V;
+ if (Val.size() != AV->Val.size()) return false;
+ for (unsigned i = 0; i < Val.size(); i++)
+ if (!Val[i]->equals(AV->Val[i])) return false;
+
+ return true;
+}
+
+bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ ConstPoolStruct *SV = (ConstPoolStruct*)V;
+ if (Val.size() != SV->Val.size()) return false;
+ for (unsigned i = 0; i < Val.size(); i++)
+ if (!Val[i]->equals(SV->Val[i])) return false;
+
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// isValueValidForType implementations
+
+bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as integers!!!
+
+ // Signed types...
+ case Type::SByteTyID:
+ return (Val <= INT8_MAX && Val >= INT8_MIN);
+ case Type::ShortTyID:
+ return (Val <= INT16_MAX && Val >= INT16_MIN);
+ case Type::IntTyID:
+ return (Val <= INT32_MAX && Val >= INT32_MIN);
+ case Type::LongTyID:
+ return true; // This is the largest type...
+ }
+ assert(0 && "WTF?");
+ return false;
+}
+
+bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as integers!!!
+
+ // Unsigned types...
+ case Type::UByteTyID:
+ return (Val <= UINT8_MAX);
+ case Type::UShortTyID:
+ return (Val <= UINT16_MAX);
+ case Type::UIntTyID:
+ return (Val <= UINT32_MAX);
+ case Type::ULongTyID:
+ return true; // This is the largest type...
+ }
+ assert(0 && "WTF?");
+ return false;
+}
+
+bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as floating point!
+
+ // TODO: Figure out how to test if a double can be cast to a float!
+ /*
+ case Type::FloatTyID:
+ return (Val <= UINT8_MAX);
+ */
+ case Type::DoubleTyID:
+ return true; // This is the largest type...
+ }
+};
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
new file mode 100644
index 0000000..550c4f0
--- /dev/null
+++ b/lib/VMCore/Function.cpp
@@ -0,0 +1,75 @@
+//===-- Method.cpp - Implement the Method class ------------------*- C++ -*--=//
+//
+// This file implements the Method class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ValueHolderImpl.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/Module.h"
+#include "llvm/Method.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/iOther.h"
+
+// Instantiate Templates - This ugliness is the price we have to pay
+// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
+//
+template class ValueHolder<MethodArgument, Method>;
+template class ValueHolder<BasicBlock , Method>;
+
+Method::Method(const MethodType *Ty, const string &name)
+ : SymTabValue(Ty, Value::MethodVal, name), BasicBlocks(this),
+ ArgumentList(this, this) {
+ assert(Ty->isMethodType() && "Method signature must be of method type!");
+ Parent = 0;
+}
+
+Method::~Method() {
+ dropAllReferences(); // After this it is safe to delete instructions.
+
+ // TODO: Should remove from the end, not the beginning of vector!
+ BasicBlocksType::iterator BI = BasicBlocks.begin();
+ while ((BI = BasicBlocks.begin()) != BasicBlocks.end())
+ delete BasicBlocks.remove(BI);
+
+ // Delete all of the method arguments and unlink from symbol table...
+ ArgumentList.delete_all();
+ ArgumentList.setParent(0);
+}
+
+// Specialize setName to take care of symbol table majik
+void Method::setName(const string &name) {
+ Module *P;
+ if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (P && getName() != "") P->getSymbolTableSure()->insert(this);
+}
+
+void Method::setParent(Module *parent) {
+ Parent = parent;
+
+ // Relink symbol tables together...
+ setParentSymTab(Parent ? Parent->getSymbolTableSure() : 0);
+}
+
+const Type *Method::getReturnType() const {
+ return ((const MethodType *)getType())->getReturnType();
+}
+
+const MethodType *Method::getMethodType() const {
+ return (const MethodType *)getType();
+}
+
+// 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 Method::dropAllReferences() {
+ for_each(BasicBlocks.begin(), BasicBlocks.end(),
+ std::mem_fun(&BasicBlock::dropAllReferences));
+}
diff --git a/lib/VMCore/InstrTypes.cpp b/lib/VMCore/InstrTypes.cpp
new file mode 100644
index 0000000..29b293f
--- /dev/null
+++ b/lib/VMCore/InstrTypes.cpp
@@ -0,0 +1,66 @@
+//===-- InstrTypes.cpp - Implement Instruction subclasses --------*- C++ -*--=//
+//
+// This file implements
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iOther.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Method.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/Type.h"
+#include <algorithm>
+
+//===----------------------------------------------------------------------===//
+// TerminatorInst Class
+//===----------------------------------------------------------------------===//
+
+TerminatorInst::TerminatorInst(unsigned iType)
+ : Instruction(Type::VoidTy, iType, "") {
+}
+
+
+//===----------------------------------------------------------------------===//
+// MethodArgument Class
+//===----------------------------------------------------------------------===//
+
+// Specialize setName to take care of symbol table majik
+void MethodArgument::setName(const string &name) {
+ Method *P;
+ if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (P && hasName()) P->getSymbolTable()->insert(this);
+}
+
+
+//===----------------------------------------------------------------------===//
+// PHINode Class
+//===----------------------------------------------------------------------===//
+
+PHINode::PHINode(const Type *Ty, const string &name)
+ : Instruction(Ty, Instruction::PHINode, name) {
+}
+
+PHINode::PHINode(const PHINode &PN)
+ : Instruction(PN.getType(), Instruction::PHINode) {
+
+ for (unsigned i = 0; i < PN.IncomingValues.size(); i++)
+ IncomingValues.push_back(Use(PN.IncomingValues[i], this));
+}
+
+void PHINode::dropAllReferences() {
+ IncomingValues.clear();
+}
+
+bool PHINode::setOperand(unsigned i, Value *Val) {
+ assert(Val && "PHI node must only reference nonnull definitions!");
+ if (i >= IncomingValues.size()) return false;
+
+ IncomingValues[i] = Val;
+ return true;
+}
+
+void PHINode::addIncoming(Value *D) {
+ IncomingValues.push_back(Use(D, this));
+}
+
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
new file mode 100644
index 0000000..4b528f0
--- /dev/null
+++ b/lib/VMCore/Instruction.cpp
@@ -0,0 +1,61 @@
+//===-- Instruction.cpp - Implement the Instruction class --------*- C++ -*--=//
+//
+// This file implements the Instruction class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instruction.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Method.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/iBinary.h"
+#include "llvm/iUnary.h"
+
+Instruction::Instruction(const Type *ty, unsigned it, const string &Name)
+ : User(ty, Value::InstructionVal, Name) {
+ Parent = 0;
+ iType = it;
+}
+
+Instruction::~Instruction() {
+ assert(getParent() == 0 && "Instruction still embeded in basic block!");
+}
+
+// Specialize setName to take care of symbol table majik
+void Instruction::setName(const string &name) {
+ BasicBlock *P = 0; Method *PP = 0;
+ if ((P = getParent()) && (PP = P->getParent()) && hasName())
+ PP->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (PP && hasName()) PP->getSymbolTableSure()->insert(this);
+}
+
+Instruction *Instruction::getBinaryOperator(unsigned Op, Value *S1, Value *S2) {
+ switch (Op) {
+ case Add:
+ return new AddInst(S1, S2);
+ case Sub:
+ return new SubInst(S1, S2);
+
+ case SetLT:
+ case SetGT:
+ case SetLE:
+ case SetGE:
+ case SetEQ:
+ case SetNE:
+ return new SetCondInst((BinaryOps)Op, S1, S2);
+
+ default:
+ cerr << "Don't know how to GetBinaryOperator " << Op << endl;
+ return 0;
+ }
+}
+
+
+Instruction *Instruction::getUnaryOperator(unsigned Op, Value *Source) {
+ switch (Op) {
+ default:
+ cerr << "Don't know how to GetUnaryOperator " << Op << endl;
+ return 0;
+ }
+}
diff --git a/lib/VMCore/Makefile b/lib/VMCore/Makefile
new file mode 100644
index 0000000..7d1289c
--- /dev/null
+++ b/lib/VMCore/Makefile
@@ -0,0 +1,7 @@
+
+LEVEL = ../..
+
+LIBRARYNAME = vmcore
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
new file mode 100644
index 0000000..4f2eee4
--- /dev/null
+++ b/lib/VMCore/Module.cpp
@@ -0,0 +1,42 @@
+//===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=//
+//
+// This file implements the Module class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ValueHolderImpl.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Method.h"
+#include "llvm/Module.h"
+
+// Instantiate Templates - This ugliness is the price we have to pay
+// for having a DefHolderImpl.h file seperate from DefHolder.h! :(
+//
+template class ValueHolder<Method, Module>;
+
+Module::Module()
+ : SymTabValue(0/*TODO: REAL TYPE*/, Value::ModuleVal, ""),
+ MethodList(this, this) {
+}
+
+Module::~Module() {
+ dropAllReferences();
+ MethodList.delete_all();
+ MethodList.setParent(0);
+}
+
+
+// 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 Module::dropAllReferences() {
+ MethodListType::iterator MI = MethodList.begin();
+ for (; MI != MethodList.end(); MI++)
+ (*MI)->dropAllReferences();
+}
diff --git a/lib/VMCore/SlotCalculator.cpp b/lib/VMCore/SlotCalculator.cpp
new file mode 100644
index 0000000..01fae37
--- /dev/null
+++ b/lib/VMCore/SlotCalculator.cpp
@@ -0,0 +1,195 @@
+//===-- SlotCalculator.cpp - Calculate what slots values land in ------------=//
+//
+// This file implements a useful analysis step to figure out what numbered
+// slots values in a program will land in (keeping track of per plane
+// information as required.
+//
+// This is used primarily for when writing a file to disk, either in bytecode
+// or source format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/SlotCalculator.h"
+#include "llvm/ConstantPool.h"
+#include "llvm/Method.h"
+#include "llvm/Module.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/ConstPoolVals.h"
+#include "llvm/iOther.h"
+#include "llvm/DerivedTypes.h"
+
+SlotCalculator::SlotCalculator(const Module *M, bool IgnoreNamed) {
+ IgnoreNamedNodes = IgnoreNamed;
+ TheModule = M;
+
+ // Preload table... Make sure that all of the primitive types are in the table
+ // and that their Primitive ID is equal to their slot #
+ //
+ for (unsigned i = 0; i < Type::FirstDerivedTyID; ++i) {
+ assert(Type::getPrimitiveType((Type::PrimitiveID)i));
+ insertVal(Type::getPrimitiveType((Type::PrimitiveID)i));
+ }
+
+ if (M == 0) return; // Empty table...
+
+ bool Result = processModule(M);
+ assert(Result == false && "Error in processModule!");
+}
+
+SlotCalculator::SlotCalculator(const Method *M, bool IgnoreNamed) {
+ IgnoreNamedNodes = IgnoreNamed;
+ TheModule = M ? M->getParent() : 0;
+
+ // Preload table... Make sure that all of the primitive types are in the table
+ // and that their Primitive ID is equal to their slot #
+ //
+ for (unsigned i = 0; i < Type::FirstDerivedTyID; ++i) {
+ assert(Type::getPrimitiveType((Type::PrimitiveID)i));
+ insertVal(Type::getPrimitiveType((Type::PrimitiveID)i));
+ }
+
+ if (TheModule == 0) return; // Empty table...
+
+ bool Result = processModule(TheModule);
+ assert(Result == false && "Error in processModule!");
+
+ incorporateMethod(M);
+}
+
+void SlotCalculator::incorporateMethod(const Method *M) {
+ assert(ModuleLevel.size() == 0 && "Module already incorporated!");
+
+ // Save the Table state before we process the method...
+ for (unsigned i = 0; i < Table.size(); ++i) {
+ ModuleLevel.push_back(Table[i].size());
+ }
+
+ // Process the method to incorporate its values into our table
+ processMethod(M);
+}
+
+void SlotCalculator::purgeMethod() {
+ assert(ModuleLevel.size() != 0 && "Module not incorporated!");
+ unsigned NumModuleTypes = ModuleLevel.size();
+
+ // First, remove values from existing type planes
+ for (unsigned i = 0; i < NumModuleTypes; ++i) {
+ unsigned ModuleSize = ModuleLevel[i]; // Size of plane before method came
+ while (Table[i].size() != ModuleSize) {
+ NodeMap.erase(NodeMap.find(Table[i].back())); // Erase from nodemap
+ Table[i].pop_back(); // Shrink plane
+ }
+ }
+
+ // We don't need this state anymore, free it up.
+ ModuleLevel.clear();
+
+ // Next, remove any type planes defined by the method...
+ while (NumModuleTypes != Table.size()) {
+ TypePlane &Plane = Table.back();
+ while (Plane.size()) {
+ NodeMap.erase(NodeMap.find(Plane.back())); // Erase from nodemap
+ Plane.pop_back(); // Shrink plane
+ }
+
+ Table.pop_back(); // Nuke the plane, we don't like it.
+ }
+}
+
+bool SlotCalculator::processConstant(const ConstPoolVal *CPV) {
+ //cerr << "Inserting constant: '" << CPV->getStrValue() << endl;
+ insertVal(CPV);
+ return false;
+}
+
+// processType - This callback occurs when an derived type is discovered
+// at the class level. This activity occurs when processing a constant pool.
+//
+bool SlotCalculator::processType(const Type *Ty) {
+ //cerr << "processType: " << Ty->getName() << endl;
+ // TODO: Don't leak memory!!! Free this in the dtor!
+ insertVal(new ConstPoolType(Ty));
+ return false;
+}
+
+bool SlotCalculator::visitMethod(const Method *M) {
+ //cerr << "visitMethod: '" << M->getType()->getName() << "'\n";
+ insertVal(M);
+ return false;
+}
+
+bool SlotCalculator::processMethodArgument(const MethodArgument *MA) {
+ insertVal(MA);
+ return false;
+}
+
+bool SlotCalculator::processBasicBlock(const BasicBlock *BB) {
+ insertVal(BB);
+ ModuleAnalyzer::processBasicBlock(BB); // Lets visit the instructions too!
+ return false;
+}
+
+bool SlotCalculator::processInstruction(const Instruction *I) {
+ insertVal(I);
+ return false;
+}
+
+int SlotCalculator::getValSlot(const Value *D) const {
+ map<const Value*, unsigned>::const_iterator I = NodeMap.find(D);
+ if (I == NodeMap.end()) return -1;
+
+ return (int)I->second;
+}
+
+void SlotCalculator::insertVal(const Value *D) {
+ if (D == 0) return;
+
+ // If this node does not contribute to a plane, or if the node has a
+ // name and we don't want names, then ignore the silly node...
+ //
+ if (D->getType() == Type::VoidTy || (IgnoreNamedNodes && D->hasName()))
+ return;
+
+ const Type *Typ = D->getType();
+ unsigned Ty = Typ->getPrimitiveID();
+ if (Typ->isDerivedType()) {
+ int DefSlot = getValSlot(Typ);
+ if (DefSlot == -1) { // Have we already entered this type?
+ // This can happen if a type is first seen in an instruction. For
+ // example, if you say 'malloc uint', this defines a type 'uint*' that
+ // may be undefined at this point.
+ //
+ cerr << "SHOULDNT HAPPEN Adding Type ba: " << Typ->getName() << endl;
+ assert(0 && "SHouldn't this be taken care of by processType!?!?!");
+ // Nope... add this to the Type plane now!
+ insertVal(Typ);
+
+ DefSlot = getValSlot(Typ);
+ assert(DefSlot >= 0 && "Type didn't get inserted correctly!");
+ }
+ Ty = (unsigned)DefSlot;
+ }
+
+ if (Table.size() <= Ty) // Make sure we have the type plane allocated...
+ Table.resize(Ty+1, TypePlane());
+
+ // Insert node into table and NodeMap...
+ NodeMap[D] = Table[Ty].size();
+
+ if (Typ == Type::TypeTy && // If it's a type constant, add the Type also
+ D->getValueType() != Value::TypeVal) {
+ assert(D->getValueType() == Value::ConstantVal &&
+ "All Type instances should be constant types!");
+
+ const ConstPoolType *CPT = (const ConstPoolType*)D;
+ int Slot = getValSlot(CPT->getValue());
+ if (Slot == -1) {
+ // Only add if it's not already here!
+ NodeMap[CPT->getValue()] = Table[Ty].size();
+ } else if (!CPT->hasName()) { // If the type has no name...
+ NodeMap[D] = (unsigned)Slot; // Don't readd type, merge.
+ return;
+ }
+ }
+ Table[Ty].push_back(D);
+}
diff --git a/lib/VMCore/SymbolTable.cpp b/lib/VMCore/SymbolTable.cpp
new file mode 100644
index 0000000..395c23f
--- /dev/null
+++ b/lib/VMCore/SymbolTable.cpp
@@ -0,0 +1,106 @@
+//===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=//
+//
+// This file implements the SymbolTable class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/SymbolTable.h"
+#include "llvm/InstrTypes.h"
+#ifndef NDEBUG
+#include "llvm/BasicBlock.h" // Required for assertions to work.
+#include "llvm/Type.h"
+#endif
+
+SymbolTable::~SymbolTable() {
+#ifndef NDEBUG // Only do this in -g mode...
+ bool Good = true;
+ for (iterator i = begin(); i != end(); i++) {
+ if (i->second.begin() != i->second.end()) {
+ for (type_iterator I = i->second.begin(); I != i->second.end(); I++)
+ cerr << "Value still in symbol table! Type = " << i->first->getName()
+ << " Name = " << I->first << endl;
+ Good = false;
+ }
+ }
+ assert(Good && "Values remain in symbol table!");
+#endif
+}
+
+SymbolTable::type_iterator SymbolTable::type_find(const Value *D) {
+ assert(D->hasName() && "type_find(Value*) only works on named nodes!");
+ return type_find(D->getType(), D->getName());
+}
+
+
+// find - returns end(Ty->getIDNumber()) on failure...
+SymbolTable::type_iterator SymbolTable::type_find(const Type *Ty,
+ const string &Name) {
+ iterator I = find(Ty);
+ if (I == end()) { // Not in collection yet... insert dummy entry
+ (*this)[Ty] = VarMap();
+ I = find(Ty);
+ assert(I != end() && "How did insert fail?");
+ }
+
+ return I->second.find(Name);
+}
+
+
+// lookup - Returns null on failure...
+Value *SymbolTable::lookup(const Type *Ty, const string &Name) {
+ iterator I = find(Ty);
+ if (I != end()) { // We have symbols in that plane...
+ type_iterator J = I->second.find(Name);
+ if (J != I->second.end()) // and the name is in our hash table...
+ return J->second;
+ }
+
+ return ParentSymTab ? ParentSymTab->lookup(Ty, Name) : 0;
+}
+
+void SymbolTable::remove(Value *N) {
+ assert(N->hasName() && "Value doesn't have name!");
+ assert(type_find(N) != type_end(N->getType()) &&
+ "Value not in symbol table!");
+ type_remove(type_find(N));
+}
+
+
+#define DEBUG_SYMBOL_TABLE 0
+
+Value *SymbolTable::type_remove(const type_iterator &It) {
+ Value *Result = It->second;
+#if DEBUG_SYMBOL_TABLE
+ cerr << this << " Removing Value: " << Result->getName() << endl;
+#endif
+
+ find(Result->getType())->second.erase(It);
+
+ return Result;
+}
+
+void SymbolTable::insert(Value *N) {
+ assert(N->hasName() && "Value must be named to go into symbol table!");
+
+ // TODO: The typeverifier should catch this when its implemented
+ if (lookup(N->getType(), N->getName())) {
+ cerr << "SymbolTable WARNING: Name already in symbol table: '"
+ << N->getName() << "'\n";
+ abort(); // TODO: REMOVE THIS
+ }
+
+#if DEBUG_SYMBOL_TABLE
+ cerr << this << " Inserting definition: " << N->getName() << ": "
+ << N->getType()->getName() << endl;
+#endif
+
+ iterator I = find(N->getType());
+ if (I == end()) { // Not in collection yet... insert dummy entry
+ (*this)[N->getType()] = VarMap();
+ I = find(N->getType());
+ assert(I != end() && "How did insert fail?");
+ }
+
+ I->second.insert(make_pair(N->getName(), N));
+}
+
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
new file mode 100644
index 0000000..cf16309
--- /dev/null
+++ b/lib/VMCore/Type.cpp
@@ -0,0 +1,308 @@
+//===-- Type.cpp - Implement the Type class ----------------------*- C++ -*--=//
+//
+// This file implements the Type class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DerivedTypes.h"
+#include "llvm/Tools/StringExtras.h"
+
+//===----------------------------------------------------------------------===//
+// Type Class Implementation
+//===----------------------------------------------------------------------===//
+
+static unsigned CurUID = 0;
+static vector<const Type *> UIDMappings;
+
+Type::Type(const string &name, PrimitiveID id)
+ : Value(Type::TypeTy, Value::TypeVal, name) {
+ ID = id;
+ ConstRulesImpl = 0;
+
+ UID = CurUID++; // Assign types UID's as they are created
+ UIDMappings.push_back(this);
+}
+
+const Type *Type::getUniqueIDType(unsigned UID) {
+ assert(UID < UIDMappings.size() &&
+ "Type::getPrimitiveType: UID out of range!");
+ return UIDMappings[UID];
+}
+
+const Type *Type::getPrimitiveType(PrimitiveID IDNumber) {
+ switch (IDNumber) {
+ case VoidTyID : return VoidTy;
+ case BoolTyID : return BoolTy;
+ case UByteTyID : return UByteTy;
+ case SByteTyID : return SByteTy;
+ case UShortTyID: return UShortTy;
+ case ShortTyID : return ShortTy;
+ case UIntTyID : return UIntTy;
+ case IntTyID : return IntTy;
+ case ULongTyID : return ULongTy;
+ case LongTyID : return LongTy;
+ case FloatTyID : return FloatTy;
+ case DoubleTyID: return DoubleTy;
+ case TypeTyID : return TypeTy;
+ case LabelTyID : return LabelTy;
+ case LockTyID : return LockTy;
+ case FillerTyID: return new Type("XXX FILLER XXX", FillerTyID); // TODO:KILLME
+ default:
+ return 0;
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Auxilliary classes
+//===----------------------------------------------------------------------===//
+//
+// These classes are used to implement specialized behavior for each different
+// type.
+//
+class SignedIntType : public Type {
+ int Size;
+public:
+ SignedIntType(const string &Name, PrimitiveID id, int size) : Type(Name, id) {
+ Size = size;
+ }
+
+ // isSigned - Return whether a numeric type is signed.
+ virtual bool isSigned() const { return 1; }
+};
+
+class UnsignedIntType : public Type {
+ uint64_t Size;
+public:
+ UnsignedIntType(const string &N, PrimitiveID id, int size) : Type(N, id) {
+ Size = size;
+ }
+
+ // isUnsigned - Return whether a numeric type is signed.
+ virtual bool isUnsigned() const { return 1; }
+};
+
+static struct TypeType : public Type {
+ TypeType() : Type("type", TypeTyID) {}
+} TheTypeType; // Implement the type that is global.
+
+
+//===----------------------------------------------------------------------===//
+// Static 'Type' data
+//===----------------------------------------------------------------------===//
+
+const Type *Type::VoidTy = new Type("void" , VoidTyID),
+ *Type::BoolTy = new Type("bool" , BoolTyID),
+ *Type::SByteTy = new SignedIntType("sbyte" , SByteTyID, 1),
+ *Type::UByteTy = new UnsignedIntType("ubyte" , UByteTyID, 1),
+ *Type::ShortTy = new SignedIntType("short" , ShortTyID, 2),
+ *Type::UShortTy = new UnsignedIntType("ushort", UShortTyID, 2),
+ *Type::IntTy = new SignedIntType("int" , IntTyID, 4),
+ *Type::UIntTy = new UnsignedIntType("uint" , UIntTyID, 4),
+ *Type::LongTy = new SignedIntType("long" , LongTyID, 8),
+ *Type::ULongTy = new UnsignedIntType("ulong" , ULongTyID, 8),
+ *Type::FloatTy = new Type("float" , FloatTyID),
+ *Type::DoubleTy = new Type("double", DoubleTyID),
+ *Type::TypeTy = &TheTypeType,
+ *Type::LabelTy = new Type("label" , LabelTyID),
+ *Type::LockTy = new Type("lock" , LockTyID);
+
+
+//===----------------------------------------------------------------------===//
+// Derived Type Implementations
+//===----------------------------------------------------------------------===//
+
+// Make sure that only one instance of a particular type may be created on any
+// given run of the compiler...
+//
+// TODO: This list should be kept in sorted order so that we can do a binary
+// TODO: search instead of linear search!
+//
+// TODO: This should be templatized so that every derived type can use the same
+// TODO: code!
+//
+#define TEST_MERGE_TYPES 0
+
+#if TEST_MERGE_TYPES
+#include "llvm/Assembly/Writer.h"
+#endif
+
+//===----------------------------------------------------------------------===//
+// Derived Type Constructors
+//===----------------------------------------------------------------------===//
+
+MethodType::MethodType(const Type *Result, const vector<const Type*> &Params,
+ const string &Name)
+ : Type(Name, MethodTyID), ResultType(Result), ParamTys(Params) {
+}
+
+ArrayType::ArrayType(const Type *ElType, int NumEl, const string &Name)
+ : Type(Name, ArrayTyID), ElementType(ElType) {
+ NumElements = NumEl;
+}
+
+StructType::StructType(const vector<const Type*> &Types, const string &Name)
+ : Type(Name, StructTyID), ETypes(Types) {
+}
+
+PointerType::PointerType(const Type *E)
+ : Type(E->getName() + " *", PointerTyID), ValueType(E) {
+}
+
+//===----------------------------------------------------------------------===//
+// Derived Type Creator Functions
+//===----------------------------------------------------------------------===//
+
+const MethodType *MethodType::getMethodType(const Type *ReturnType,
+ const vector<const Type*> &Params) {
+ static vector<const MethodType*> ExistingMethodTypesCache;
+ for (unsigned i = 0; i < ExistingMethodTypesCache.size(); i++) {
+ const MethodType *T = ExistingMethodTypesCache[i];
+ if (T->getReturnType() == ReturnType) {
+ const ParamTypes &EParams = T->getParamTypes();
+ ParamTypes::const_iterator I = Params.begin();
+ ParamTypes::const_iterator J = EParams.begin();
+ for (; I != Params.end() && J != EParams.end(); I++, J++)
+ if (*I != *J) break; // These types aren't equal!
+
+ if (I == Params.end() && J == EParams.end()) {
+#if TEST_MERGE_TYPES == 2
+ ostream_iterator<const Type*> out(cerr, ", ");
+ cerr << "Type: \"";
+ copy(Params.begin(), Params.end(), out);
+ cerr << "\"\nEquals: \"";
+ copy(EParams.begin(), EParams.end(), out);
+ cerr << "\"" << endl;
+#endif
+ return T;
+ }
+ }
+ }
+#if TEST_MERGE_TYPES == 2
+ ostream_iterator<const Type*> out(cerr, ", ");
+ cerr << "Input Types: ";
+ copy(Params.begin(), Params.end(), out);
+ cerr << endl;
+#endif
+
+ // Calculate the string name for the new type...
+ string Name = ReturnType->getName() + " (";
+ for (ParamTypes::const_iterator I = Params.begin();
+ I != Params.end(); I++) {
+ if (I != Params.begin())
+ Name += ", ";
+ Name += (*I)->getName();
+ }
+ Name += ")";
+
+#if TEST_MERGE_TYPES
+ cerr << "Derived new type: " << Name << endl;
+#endif
+
+ MethodType *Result = new MethodType(ReturnType, Params, Name);
+ ExistingMethodTypesCache.push_back(Result);
+ return Result;
+}
+
+
+const ArrayType *ArrayType::getArrayType(const Type *ElementType,
+ int NumElements = -1) {
+ static vector<const ArrayType*> ExistingTypesCache;
+
+ // Search cache for value...
+ for (unsigned i = 0; i < ExistingTypesCache.size(); i++) {
+ const ArrayType *T = ExistingTypesCache[i];
+
+ if (T->getElementType() == ElementType &&
+ T->getNumElements() == NumElements)
+ return T;
+ }
+
+ // Value not found. Derive a new type!
+ string Name = "[";
+ if (NumElements != -1) Name += itostr(NumElements) + " x ";
+
+ Name += ElementType->getName();
+
+ ArrayType *Result = new ArrayType(ElementType, NumElements, Name + "]");
+ ExistingTypesCache.push_back(Result);
+
+#if TEST_MERGE_TYPES
+ cerr << "Derived new type: " << Result->getName() << endl;
+#endif
+ return Result;
+}
+
+const StructType *StructType::getStructType(const ElementTypes &ETypes) {
+ static vector<const StructType*> ExistingStructTypesCache;
+
+ for (unsigned i = 0; i < ExistingStructTypesCache.size(); i++) {
+ const StructType *T = ExistingStructTypesCache[i];
+
+ const ElementTypes &Elements = T->getElementTypes();
+ ElementTypes::const_iterator I = ETypes.begin();
+ ElementTypes::const_iterator J = Elements.begin();
+ for (; I != ETypes.end() && J != Elements.end(); I++, J++)
+ if (*I != *J) break; // These types aren't equal!
+
+ if (I == ETypes.end() && J == Elements.end()) {
+#if TEST_MERGE_TYPES == 2
+ ostream_iterator<const Type*> out(cerr, ", ");
+ cerr << "Type: \"";
+ copy(ETypes.begin(), ETypes.end(), out);
+ cerr << "\"\nEquals: \"";
+ copy(Elements.begin(), Elements.end(), out);
+ cerr << "\"" << endl;
+#endif
+ return T;
+ }
+ }
+
+#if TEST_MERGE_TYPES == 2
+ ostream_iterator<const Type*> out(cerr, ", ");
+ cerr << "Input Types: ";
+ copy(ETypes.begin(), ETypes.end(), out);
+ cerr << endl;
+#endif
+
+ // Calculate the string name for the new type...
+ string Name = "{ ";
+ for (ElementTypes::const_iterator I = ETypes.begin();
+ I != ETypes.end(); I++) {
+ if (I != ETypes.begin())
+ Name += ", ";
+ Name += (*I)->getName();
+ }
+ Name += " }";
+
+#if TEST_MERGE_TYPES
+ cerr << "Derived new type: " << Name << endl;
+#endif
+
+ StructType *Result = new StructType(ETypes, Name);
+ ExistingStructTypesCache.push_back(Result);
+ return Result;
+}
+
+
+const PointerType *PointerType::getPointerType(const Type *ValueType) {
+ static vector<const PointerType*> ExistingTypesCache;
+
+ // Search cache for value...
+ for (unsigned i = 0; i < ExistingTypesCache.size(); i++) {
+ const PointerType *T = ExistingTypesCache[i];
+
+ if (T->getValueType() == ValueType)
+ return T;
+ }
+
+ PointerType *Result = new PointerType(ValueType);
+ ExistingTypesCache.push_back(Result);
+
+#if TEST_MERGE_TYPES
+ cerr << "Derived new type: " << Result->getName() << endl;
+#endif
+ return Result;
+}
+
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
new file mode 100644
index 0000000..1c3f76b
--- /dev/null
+++ b/lib/VMCore/Value.cpp
@@ -0,0 +1,143 @@
+//===-- Value.cpp - Implement the Value class -----------------------------===//
+//
+// This file implements the Value class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ValueHolderImpl.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/SymTabValue.h"
+#include "llvm/ConstantPool.h"
+#include "llvm/ConstPoolVals.h"
+#include "llvm/Type.h"
+#ifndef NDEBUG // Only in -g mode...
+#include "llvm/Assembly/Writer.h"
+#endif
+#include <algorithm>
+
+//===----------------------------------------------------------------------===//
+// Value Class
+//===----------------------------------------------------------------------===//
+
+Value::Value(const Type *ty, ValueTy vty, const string &name = "") : Name(name){
+ Ty = ty;
+ VTy = vty;
+}
+
+Value::~Value() {
+#ifndef NDEBUG // Only in -g mode...
+ if (Uses.begin() != Uses.end()) {
+ for (use_const_iterator I = Uses.begin(); I != Uses.end(); I++)
+ cerr << "Use still stuck around after Def is destroyed:" << *I << endl;
+ }
+#endif
+ assert(Uses.begin() == Uses.end());
+}
+
+void Value::replaceAllUsesWith(Value *D) {
+ assert(D && "Value::replaceAllUsesWith(<null>) is invalid!");
+ while (!Uses.empty()) {
+ User *Use = Uses.front();
+#ifndef NDEBUG
+ unsigned NumUses = Uses.size();
+#endif
+ Use->replaceUsesOfWith(this, D);
+
+#ifndef NDEBUG // only in -g mode...
+ if (Uses.size() == NumUses)
+ cerr << "Use: " << Use << "replace with: " << D;
+#endif
+ assert(Uses.size() != NumUses && "Didn't remove definition!");
+ }
+}
+
+void Value::killUse(User *i) {
+ if (i == 0) return;
+ use_iterator I = find(Uses.begin(), Uses.end(), i);
+
+ assert(I != Uses.end() && "Use not in uses list!!");
+ Uses.erase(I);
+}
+
+User *Value::use_remove(use_iterator &I) {
+ assert(I != Uses.end() && "Trying to remove the end of the use list!!!");
+ User *i = *I;
+ I = Uses.erase(I);
+ return i;
+}
+
+
+//===----------------------------------------------------------------------===//
+// User Class
+//===----------------------------------------------------------------------===//
+
+User::User(const Type *Ty, ValueTy vty, const string &name)
+ : Value(Ty, vty, name) {
+}
+
+// replaceUsesOfWith - Replaces all references to the "From" definition with
+// references to the "To" definition.
+//
+void User::replaceUsesOfWith(Value *From, Value *To) {
+ if (From == To) return; // Duh what?
+
+ for (unsigned OpNum = 0; Value *D = getOperand(OpNum); OpNum++) {
+ if (D == From) { // Okay, this operand is pointing to our fake def.
+ // The side effects of this setOperand call include linking to
+ // "To", adding "this" to the uses list of To, and
+ // most importantly, removing "this" from the use list of "From".
+ setOperand(OpNum, To); // Fix it now...
+ }
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// SymTabValue Class
+//===----------------------------------------------------------------------===//
+
+// Instantiate Templates - This ugliness is the price we have to pay
+// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
+//
+template class ValueHolder<ConstPoolVal, SymTabValue>;
+
+SymTabValue::SymTabValue(const Type *Ty, ValueTy dty, const string &name = "")
+ : Value(Ty, dty, name), ConstPool(this) {
+ ParentSymTab = SymTab = 0;
+}
+
+
+SymTabValue::~SymTabValue() {
+ ConstPool.dropAllReferences();
+ ConstPool.delete_all();
+ ConstPool.setParent(0);
+
+ delete SymTab;
+}
+
+void SymTabValue::setParentSymTab(SymbolTable *ST) {
+ ParentSymTab = ST;
+ if (SymTab)
+ SymTab->setParentSymTab(ST);
+}
+
+SymbolTable *SymTabValue::getSymbolTableSure() {
+ if (!SymTab) SymTab = new SymbolTable(ParentSymTab);
+ return SymTab;
+}
+
+// hasSymbolTable() - Returns true if there is a symbol table allocated to
+// this object AND if there is at least one name in it!
+//
+bool SymTabValue::hasSymbolTable() const {
+ if (!SymTab) return false;
+
+ for (SymbolTable::const_iterator I = SymTab->begin();
+ I != SymTab->end(); I++) {
+ if (I->second.begin() != I->second.end())
+ return true; // Found nonempty type plane!
+ }
+
+ return false;
+}
diff --git a/lib/VMCore/ValueHolderImpl.h b/lib/VMCore/ValueHolderImpl.h
new file mode 100644
index 0000000..ecafd47
--- /dev/null
+++ b/lib/VMCore/ValueHolderImpl.h
@@ -0,0 +1,85 @@
+//===-- llvm/ValueHolderImpl.h - Implement ValueHolder template --*- C++ -*--=//
+//
+// This file implements the ValueHolder class. This is kept out of line because
+// it tends to pull in a lot of dependencies on other headers and most files
+// don't need all that crud.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_VALUEHOLDER_IMPL_H
+#define LLVM_VALUEHOLDER_IMPL_H
+
+#include "llvm/ValueHolder.h"
+#include "llvm/SymbolTable.h"
+#include <algorithm>
+
+template<class ValueSubclass, class ItemParentType>
+void ValueHolder<ValueSubclass,ItemParentType>::setParent(SymTabValue *P) {
+ if (Parent) { // Remove all of the items from the old symbol table..
+ SymbolTable *SymTab = Parent->getSymbolTable();
+ for (iterator I = begin(); I != end(); I++)
+ if ((*I)->hasName()) SymTab->remove(*I);
+ }
+
+ Parent = P;
+
+ if (Parent) { // Remove all of the items from the old symbol table..
+ SymbolTable *SymTab = Parent->getSymbolTableSure();
+ for (iterator I = begin(); I != end(); I++)
+ if ((*I)->hasName()) SymTab->insert(*I);
+ }
+}
+
+
+template<class ValueSubclass, class ItemParentType>
+void ValueHolder<ValueSubclass,ItemParentType>::remove(ValueSubclass *D) {
+ iterator I(find(begin(), end(), D));
+ assert(I != end() && "Value not in ValueHolder!!");
+ remove(I);
+}
+
+// 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.
+//
+template<class ValueSubclass, class ItemParentType>
+ValueSubclass *ValueHolder<ValueSubclass,ItemParentType>::remove(iterator &DI) {
+ assert(DI != ValueList.end() &&
+ "Trying to remove the end of the def list!!!");
+
+ ValueSubclass *i = *DI;
+ DI = ValueList.erase(DI);
+
+ i->setParent(0); // I don't own you anymore... byebye...
+
+ // You don't get to be in the symbol table anymore... byebye
+ if (i->hasName() && Parent)
+ Parent->getSymbolTable()->remove(i);
+
+ return i;
+}
+
+template<class ValueSubclass, class ItemParentType>
+void ValueHolder<ValueSubclass,ItemParentType>::push_front(ValueSubclass *Inst) {
+ assert(Inst->getParent() == 0 && "Value already has parent!");
+ Inst->setParent(ItemParent);
+
+ //ValueList.push_front(Inst);
+ ValueList.insert(ValueList.begin(), Inst);
+
+ if (Inst->hasName() && Parent)
+ Parent->getSymbolTableSure()->insert(Inst);
+}
+
+template<class ValueSubclass, class ItemParentType>
+void ValueHolder<ValueSubclass,ItemParentType>::push_back(ValueSubclass *Inst) {
+ assert(Inst->getParent() == 0 && "Value already has parent!");
+ Inst->setParent(ItemParent);
+
+ ValueList.push_back(Inst);
+
+ if (Inst->hasName() && Parent)
+ Parent->getSymbolTableSure()->insert(Inst);
+}
+
+#endif
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
new file mode 100644
index 0000000..820fa5c
--- /dev/null
+++ b/lib/VMCore/Verifier.cpp
@@ -0,0 +1,94 @@
+//===-- Verifier.cpp - Implement the Module Verifier -------------*- C++ -*-==//
+//
+// This file defines the method verifier interface, that can be used for some
+// sanity checking of input to the system.
+//
+// Note that this does not provide full 'java style' security and verifications,
+// instead it just tries to ensure that code is well formed.
+//
+// . There are no duplicated names in a symbol table... ie there !exist a val
+// with the same name as something in the symbol table, but with a different
+// address as what is in the symbol table...
+// . Both of a binary operator's parameters are the same type
+// . Only PHI nodes can refer to themselves
+// . All of the constants in a switch statement are of the correct type
+// . The code is in valid SSA form
+// . It should be illegal to put a label into any other type (like a structure)
+// or to return one. [except constant arrays!]
+// . Right now 'add bool 0, 0' is valid. This isn't particularly good.
+// . Only phi nodes can be self referential: 'add int 0, 0 ; <int>:0' is bad
+// . All other things that are tested by asserts spread about the code...
+// . All basic blocks should only end with terminator insts, not contain them
+// . All methods must have >= 1 basic block
+// . Verify that none of the Def getType()'s are null.
+// . Method's cannot take a void typed parameter
+// . Verify that a method's argument list agrees with it's declared type.
+// . Verify that arrays and structures have fixed elements: No unsized arrays.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/ConstantPool.h"
+#include "llvm/Method.h"
+#include "llvm/Module.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Type.h"
+
+// Error - Define a macro to do the common task of pushing a message onto the
+// end of the error list and setting Bad to true.
+//
+#define Error(msg) do { ErrorMsgs.push_back(msg); Bad = true; } while (0)
+
+#define t(x) (1 << (unsigned)Type::x)
+
+#define SignedIntegralTypes (t(SByteTyID) | t(ShortTyID) | \
+ t(IntTyID) | t(LongTyID))
+static long UnsignedIntegralTypes = t(UByteTyID) | t(UShortTyID) |
+ t(UIntTyID) | t(ULongTyID);
+static const long FloatingPointTypes = t(FloatTyID) | t(DoubleTyID);
+
+static const long IntegralTypes = SignedIntegralTypes | UnsignedIntegralTypes;
+
+#if 0
+static long ValidTypes[Type::FirstDerivedTyID] = {
+ [(unsigned)Instruction::UnaryOps::Not] t(BoolTyID),
+ //[Instruction::UnaryOps::Add] = IntegralTypes,
+ // [Instruction::Sub] = IntegralTypes,
+};
+#endif
+
+#undef t
+
+static bool verify(const BasicBlock *BB, vector<string> &ErrorMsgs) {
+ bool Bad = false;
+ if (BB->getTerminator() == 0) Error("Basic Block does not have terminator!");
+
+
+ return Bad;
+}
+
+
+bool verify(const Method *M, vector<string> &ErrorMsgs) {
+ bool Bad = false;
+
+ for (Method::BasicBlocksType::const_iterator BBIt = M->getBasicBlocks().begin();
+ BBIt != M->getBasicBlocks().end(); BBIt++) {
+ Bad |= verify(*BBIt, ErrorMsgs);
+ }
+
+ return Bad;
+}
+
+bool verify(const Module *C, vector<string> &ErrorMsgs) {
+ bool Bad = false;
+ assert(Type::FirstDerivedTyID-1 < sizeof(long)*8 &&
+ "Resize ValidTypes table to handle more than 32 primitive types!");
+
+ for (Module::MethodListType::const_iterator MI = C->getMethodList().begin();
+ MI != C->getMethodList().end(); MI++) {
+ const Method *M = *MI;
+ Bad |= verify(M, ErrorMsgs);
+ }
+
+ return Bad;
+}
diff --git a/lib/VMCore/iBranch.cpp b/lib/VMCore/iBranch.cpp
new file mode 100644
index 0000000..05f3505
--- /dev/null
+++ b/lib/VMCore/iBranch.cpp
@@ -0,0 +1,69 @@
+//===-- iBranch.cpp - Implement the Branch instruction -----------*- C++ -*--=//
+//
+// This file implements the 'br' instruction, which can represent either a
+// conditional or unconditional branch.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iTerminators.h"
+#include "llvm/BasicBlock.h"
+#ifndef NDEBUG
+#include "llvm/Type.h" // Only used for assertions...
+#include "llvm/Assembly/Writer.h"
+#endif
+
+BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond)
+ : TerminatorInst(Instruction::Br), TrueDest(True, this),
+ FalseDest(False, this), Condition(Cond, this) {
+ assert(True != 0 && "True branch destination may not be null!!!");
+
+#ifndef NDEBUG
+ if (Cond != 0 && Cond->getType() != Type::BoolTy)
+ cerr << "Bad Condition: " << Cond << endl;
+#endif
+ assert((Cond == 0 || Cond->getType() == Type::BoolTy) &&
+ "May only branch on boolean predicates!!!!");
+}
+
+BranchInst::BranchInst(const BranchInst &BI)
+ : TerminatorInst(Instruction::Br), TrueDest(BI.TrueDest, this),
+ FalseDest(BI.FalseDest, this), Condition(BI.Condition, this) {
+}
+
+
+void BranchInst::dropAllReferences() {
+ Condition = 0;
+ TrueDest = FalseDest = 0;
+}
+
+const Value *BranchInst::getOperand(unsigned i) const {
+ return (i == 0) ? (Value*)TrueDest :
+ ((i == 1) ? (Value*)FalseDest :
+ ((i == 2) ? (Value*)Condition : 0));
+}
+
+const BasicBlock *BranchInst::getSuccessor(unsigned i) const {
+ return (i == 0) ? (const BasicBlock*)TrueDest :
+ ((i == 1) ? (const BasicBlock*)FalseDest : 0);
+}
+
+bool BranchInst::setOperand(unsigned i, Value *Val) {
+ switch (i) {
+ case 0:
+ assert(Val && "Can't change primary direction to 0!");
+ assert(Val->getType() == Type::LabelTy);
+ TrueDest = (BasicBlock*)Val;
+ return true;
+ case 1:
+ assert(Val == 0 || Val->getType() == Type::LabelTy);
+ FalseDest = (BasicBlock*)Val;
+ return true;
+ case 2:
+ Condition = Val;
+ assert(!Condition || Condition->getType() == Type::BoolTy &&
+ "Condition expr must be a boolean expression!");
+ return true;
+ }
+
+ return false;
+}
diff --git a/lib/VMCore/iCall.cpp b/lib/VMCore/iCall.cpp
new file mode 100644
index 0000000..9ff6bb6
--- /dev/null
+++ b/lib/VMCore/iCall.cpp
@@ -0,0 +1,48 @@
+//===-- iCall.cpp - Implement the Call & Invoke instructions -----*- C++ -*--=//
+//
+// This file implements the call and invoke instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iOther.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Method.h"
+
+CallInst::CallInst(Method *m, vector<Value*> &params,
+ const string &Name)
+ : Instruction(m->getReturnType(), Instruction::Call, Name), M(m, this) {
+
+ const MethodType* MT = M->getMethodType();
+ const MethodType::ParamTypes &PL = MT->getParamTypes();
+ assert(params.size() == PL.size());
+#ifndef NDEBUG
+ MethodType::ParamTypes::const_iterator It = PL.begin();
+#endif
+ for (unsigned i = 0; i < params.size(); i++) {
+ assert(*It++ == params[i]->getType());
+ Params.push_back(Use(params[i], this));
+ }
+}
+
+CallInst::CallInst(const CallInst &CI)
+ : Instruction(CI.getType(), Instruction::Call), M(CI.M, this) {
+ for (unsigned i = 0; i < CI.Params.size(); i++)
+ Params.push_back(Use(CI.Params[i], this));
+}
+
+void CallInst::dropAllReferences() {
+ M = 0;
+ Params.clear();
+}
+
+bool CallInst::setOperand(unsigned i, Value *Val) {
+ if (i > Params.size()) return false;
+ if (i == 0) {
+ assert(Val->getValueType() == Value::MethodVal);
+ M = (Method*)Val;
+ } else {
+ // TODO: assert = method arg type
+ Params[i-1] = Val;
+ }
+ return true;
+}
diff --git a/lib/VMCore/iOperators.cpp b/lib/VMCore/iOperators.cpp
new file mode 100644
index 0000000..c754f42
--- /dev/null
+++ b/lib/VMCore/iOperators.cpp
@@ -0,0 +1,37 @@
+//===-- iBinaryOperators.cpp - Implement the BinaryOperators -----*- C++ -*--=//
+//
+// This file implements the nontrivial binary operator instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iBinary.h"
+#include "llvm/Type.h"
+
+//===----------------------------------------------------------------------===//
+// SetCondInst Class
+//===----------------------------------------------------------------------===//
+
+SetCondInst::SetCondInst(BinaryOps opType, Value *S1, Value *S2,
+ const string &Name)
+ : BinaryOperator(opType, S1, S2, Name) {
+
+ OpType = opType;
+ setType(Type::BoolTy); // setcc instructions always return bool type.
+
+ // Make sure it's a valid type...
+ assert(getOpcode() != "Invalid opcode type to SetCondInst class!");
+}
+
+string SetCondInst::getOpcode() const {
+ switch (OpType) {
+ case SetLE: return "setle";
+ case SetGE: return "setge";
+ case SetLT: return "setlt";
+ case SetGT: return "setgt";
+ case SetEQ: return "seteq";
+ case SetNE: return "setne";
+ default:
+ assert(0 && "Invalid opcode type to SetCondInst class!");
+ return "invalid opcode type to SetCondInst";
+ }
+}
diff --git a/lib/VMCore/iReturn.cpp b/lib/VMCore/iReturn.cpp
new file mode 100644
index 0000000..7fa04fb
--- /dev/null
+++ b/lib/VMCore/iReturn.cpp
@@ -0,0 +1,25 @@
+//===-- iReturn.cpp - Implement the Return instruction -----------*- C++ -*--=//
+//
+// This file implements the Return instruction...
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iTerminators.h"
+
+ReturnInst::ReturnInst(Value *V)
+ : TerminatorInst(Instruction::Ret), Val(V, this) {
+}
+
+ReturnInst::ReturnInst(const ReturnInst &RI)
+ : TerminatorInst(Instruction::Ret), Val(RI.Val, this) {
+}
+
+void ReturnInst::dropAllReferences() {
+ Val = 0;
+}
+
+bool ReturnInst::setOperand(unsigned i, Value *V) {
+ if (i) return false;
+ Val = V;
+ return true;
+}
diff --git a/lib/VMCore/iSwitch.cpp b/lib/VMCore/iSwitch.cpp
new file mode 100644
index 0000000..2a1eec2
--- /dev/null
+++ b/lib/VMCore/iSwitch.cpp
@@ -0,0 +1,81 @@
+//===-- iSwitch.cpp - Implement the Switch instruction -----------*- C++ -*--=//
+//
+// This file implements the Switch instruction...
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/iTerminators.h"
+#include "llvm/BasicBlock.h"
+#ifndef NDEBUG
+#include "llvm/Type.h"
+#endif
+
+SwitchInst::SwitchInst(Value *V, BasicBlock *DefV)
+ : TerminatorInst(Instruction::Switch),
+ DefaultDest(DefV, this), Val(V, this) {
+ assert(Val && DefV);
+}
+
+SwitchInst::SwitchInst(const SwitchInst &SI)
+ : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest),
+ Val(SI.Val) {
+
+ for (dest_const_iterator I = SI.Destinations.begin(),
+ end = SI.Destinations.end(); I != end; ++I)
+ Destinations.push_back(dest_value(ConstPoolUse(I->first, this),
+ BasicBlockUse(I->second, this)));
+}
+
+
+void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) {
+ Destinations.push_back(dest_value(ConstPoolUse(OnVal, this),
+ BasicBlockUse(Dest, this)));
+}
+
+void SwitchInst::dropAllReferences() {
+ Val = 0;
+ DefaultDest = 0;
+ Destinations.clear();
+}
+
+const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const {
+ if (idx == 0) return DefaultDest;
+ if (idx > Destinations.size()) return 0;
+ return Destinations[idx-1].second;
+}
+
+unsigned SwitchInst::getNumOperands() const {
+ return 2+Destinations.size();
+}
+
+const Value *SwitchInst::getOperand(unsigned i) const {
+ if (i == 0) return Val;
+ else if (i == 1) return DefaultDest;
+
+ unsigned slot = (i-2) >> 1;
+ if (slot >= Destinations.size()) return 0;
+
+ if (i & 1) return Destinations[slot].second;
+ return Destinations[slot].first;
+}
+
+bool SwitchInst::setOperand(unsigned i, Value *V) {
+ if (i == 0) { Val = V; return true; }
+ else if (i == 1) {
+ assert(V->getType() == Type::LabelTy);
+ DefaultDest = (BasicBlock*)V;
+ return true;
+ }
+
+ unsigned slot = (i-2) >> 1;
+ if (slot >= Destinations.size()) return 0;
+
+ if (i & 1) {
+ assert(V->getType() == Type::LabelTy);
+ Destinations[slot].second = (BasicBlock*)V;
+ } else {
+ // TODO: assert constant
+ Destinations[slot].first = (ConstPoolVal*)V;
+ }
+ return true;
+}