[llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp

Alkis Evlogimenos alkis at cs.uiuc.edu
Mon May 24 20:51:05 PDT 2004


Changes in directory llvm-java/lib/Compiler:

Compiler.cpp updated: 1.16 -> 1.17

---
Log message:

Huge refactoring. Parsing code now lives in BytecodeParser and
Compiler uses the pimpl idiom. CompilerImpl is a BytecodeParser which
also uses a Bytecode2BasicBlockMapper (BytecodeParser) to build the
bytecode->BasicBlock map.

The refactoring of the parsing code eliminates the duplicate switches
and makes the code simpler (several bytecodes are handled by one call
iconst_<n>, bipush and sipush for example).

Some bugs in the Bytecode2BasicBlockMapper where fixes (not all basic
blocks were created).


---
Diffs of the changes:  (+406 -625)

Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.16 llvm-java/lib/Compiler/Compiler.cpp:1.17
--- llvm-java/lib/Compiler/Compiler.cpp:1.16	Mon May 24 15:00:23 2004
+++ llvm-java/lib/Compiler/Compiler.cpp	Mon May 24 20:48:00 2004
@@ -14,6 +14,7 @@
 #define DEBUG_TYPE "javacompiler"
 
 #include <llvm/Java/Bytecode.h>
+#include <llvm/Java/BytecodeParser.h>
 #include <llvm/Java/ClassFile.h>
 #include <llvm/Java/Compiler.h>
 #include <llvm/Constants.h>
@@ -23,11 +24,18 @@
 #include <llvm/Type.h>
 #include <Support/Debug.h>
 #include <Support/StringExtras.h>
+#include <stack>
+#include <vector>
 
 using namespace llvm;
 using namespace llvm::Java;
 
-namespace {
+namespace llvm { namespace Java { namespace {
+
+    typedef std::vector<BasicBlock*> BC2BBMap;
+    typedef std::stack<Value*, std::vector<Value*> > OperandStack;
+    typedef std::vector<Value*> Locals;
+
 
     inline bool isTwoSlotValue(const Value* v) {
         return v->getType() == Type::LongTy | v->getType() == Type::DoubleTy;
@@ -37,402 +45,219 @@
         return !isTwoSlotValue(v);
     }
 
-} // namespace
-
-void Compiler::compileMethodInit(Function& function,
-                                 const ClassFile& cf,
-                                 const CodeAttribute& codeAttr)
-{
-    while (!opStack_.empty())
-        opStack_.pop();
+    struct Bytecode2BasicBlockMapper
+        : public BytecodeParser<Bytecode2BasicBlockMapper> {
+    public:
+        Bytecode2BasicBlockMapper(Function& f,
+                                  BC2BBMap& m,
+                                  const CodeAttribute& c)
+            : function_(f), bc2bbMap_(m), codeAttr_(c) { }
+
+        void compute() {
+            bc2bbMap_.clear();
+            bc2bbMap_.assign(codeAttr_.getCodeSize(), NULL);
+
+            parse(codeAttr_.getCode(), codeAttr_.getCodeSize());
+
+            BasicBlock* bb = new BasicBlock("entry", &function_);
+            for (unsigned i = 0; i < bc2bbMap_.size(); ++i) {
+                if (bc2bbMap_[i])
+                    bb = bc2bbMap_[i];
+                else
+                    bc2bbMap_[i] = bb;
+            }
+        }
 
-    locals_.clear();
-    locals_.assign(codeAttr.getMaxLocals(), NULL);
+        void do_if(unsigned bcI, JSetCC cc, JType type,
+                   unsigned t, unsigned f) {
+            if (!bc2bbMap_[t])
+                bc2bbMap_[t] =
+                    new BasicBlock("bb at bc" + utostr(t), &function_);
+            if (!bc2bbMap_[f])
+                bc2bbMap_[f] =
+                    new BasicBlock("bb at bc" + utostr(f), &function_);
+        }
+
+        void do_ifcmp(unsigned bcI, JSetCC cc,
+                      unsigned t, unsigned f) {
+            if (!bc2bbMap_[t])
+                bc2bbMap_[t] =
+                    new BasicBlock("bb at bc" + utostr(t), &function_);
+            if (!bc2bbMap_[f])
+                bc2bbMap_[f] =
+                    new BasicBlock("bb at bc" + utostr(f), &function_);
+        }
+
+        void do_switch(unsigned bcI,
+                       unsigned defTarget,
+                       const SwitchCases& sw) {
+            for (unsigned i = 0; i < sw.size(); ++i) {
+                unsigned target = sw[i].second;
+                if (!bc2bbMap_[target])
+                    bc2bbMap_[target] =
+                        new BasicBlock("bb at bc" + utostr(target), &function_);
+            }
+        }
 
-    bc2bbMap_.clear();
-    bc2bbMap_.assign(codeAttr.getCodeSize(), NULL);
+    private:
+        Function& function_;
+        BC2BBMap& bc2bbMap_;
+        const CodeAttribute& codeAttr_;
+    };
+
+    struct CompilerImpl :
+        public BytecodeParser<CompilerImpl> {
+    private:
+        const Type* getType(JType type) {
+            switch (type) {
+                // FIXME: this should really be a non-void type when the object
+                // model is finalized
+            case REFERENCE: return Type::VoidTy;
+            case BOOLEAN: return Type::BoolTy;
+            case CHAR: return Type::UByteTy;
+            case FLOAT: return Type::FloatTy;
+            case DOUBLE: return Type::DoubleTy;
+            case BYTE: return Type::SByteTy;
+            case SHORT: return Type::ShortTy;
+            case INT: return Type::IntTy;
+            case LONG: return Type::LongTy;
+            default: assert(0 && "Invalid JType to Type conversion!");
+            }
 
-    const uint8_t* code = codeAttr.getCode();
-    for (unsigned i = 0; i < codeAttr.getCodeSize(); ++i) {
-        using namespace llvm::Java::Opcode;
-
-        unsigned bcStart = i;
-        bool wide = code[i] == WIDE;
-        i += wide;
-        switch (code[i]) {
-        case BIPUSH:
-        case LDC:
-        case NEWARRAY:
-            ++i;
-            break;
-        case ILOAD:
-        case LLOAD:
-        case FLOAD:
-        case DLOAD:
-        case ALOAD:
-        case ISTORE:
-        case LSTORE:
-        case FSTORE:
-        case DSTORE:
-        case ASTORE:
-        case RET:
-            i += 1 + wide;
-            break;
-        case SIPUSH:
-        case LDC_W:
-        case LDC2_W:
-        case GOTO:
-        case JSR:
-        case GETSTATIC:
-        case PUTSTATIC:
-        case GETFIELD:
-        case PUTFIELD:
-        case INVOKEVIRTUAL:
-        case INVOKESPECIAL:
-        case INVOKESTATIC:
-        case INVOKEINTERFACE:
-        case NEW:
-        case ANEWARRAY:
-        case ARRAYLENGTH:
-        case ATHROW:
-        case CHECKCAST:
-        case INSTANCEOF:
-            i += 2;
-            break;
-        case IINC:
-            i += 2 * (1 + wide);
-            break;
-        case IFEQ:
-        case IFNE:
-        case IFLT:
-        case IFGE:
-        case IFGT:
-        case IFLE:
-        case IF_ICMPEQ:
-        case IF_ICMPNE:
-        case IF_ICMPLT:
-        case IF_ICMPGE:
-        case IF_ICMPGT:
-        case IF_ICMPLE:
-        case IF_IACMPEQ:
-        case IF_IACMPNE:
-        case IFNULL:
-        case IFNONNULL: {
-            unsigned index = readUShort(code, i);
-            bc2bbMap_[bcStart] = new BasicBlock(
-                std::string("bb at bc") + utostr(bcStart), &function);
-            break;
-        }
-        case TABLESWITCH: {
-            skipPadBytes(code, i);
-            readSInt(code, i);
-            int low = readSInt(code, i);
-            int high = readSInt(code, i);
-            while (low++ <= high) {
-                unsigned bcIndex = bcStart + readSInt(code, i);
-                bc2bbMap_[bcIndex] = new BasicBlock(
-                    std::string("bb at bc") + utostr(bcIndex), &function);
-            }
-            break;
-        }
-        case LOOKUPSWITCH: {
-            skipPadBytes(code, i);
-            readSInt(code, i);
-            unsigned pairCount = readUInt(code, i);
-            while (pairCount--) {
-                readSInt(code, i);
-                unsigned bcIndex = bcStart + readSInt(code, i);
-                bc2bbMap_[bcIndex] = new BasicBlock(
-                    std::string("bb at bc") + utostr(bcIndex), &function);
-            }
-            break;
-        }
-        case XXXUNUSEDXXX:
-            throw "FIXME: create new exception class";
-        case MULTIANEWARRAY:
-            i += 3;
-            break;
-        case GOTO_W:
-        case JSR_W:
-            i+= 4;
-            break;
-        default:
-            break;
+            return NULL;
         }
-    }
 
-    BasicBlock* bb = new BasicBlock("entry", &function);
-    for (unsigned i = 0; i < codeAttr.getCodeSize(); ++i) {
-        if (bc2bbMap_[i])
-            bb = bc2bbMap_[i];
-        else
-            bc2bbMap_[i] = bb;
-    }
-}
+        Instruction::BinaryOps getSetCC(JSetCC cc) {
+            switch (cc) {
+            case EQ: return Instruction::SetEQ;
+            case NE: return Instruction::SetNE;
+            case LT: return Instruction::SetLT;
+            case GE: return Instruction::SetGE;
+            case GT: return Instruction::SetGT;
+            case LE: return Instruction::SetLE;
+            default: assert(0 && "Invalid JSetCC to BinaryOps conversion!");
+            }
+            return static_cast<Instruction::BinaryOps>(-1);
+        }
 
-Value* Compiler::getOrCreateLocal(unsigned index, const Type* type)
-{
-    if (!locals_[index]) {
-        BasicBlock* entry = bc2bbMap_[0];
-        Instruction* alloc = new AllocaInst(type);
-        locals_[index] = alloc;
-        Instruction* store =
-            new StoreInst(llvm::Constant::getNullValue(type), locals_[index]);
-        entry->getInstList().push_front(store);
-        entry->getInstList().push_front(alloc);
-    }
+        void compileMethodInit(Function& function,
+                               const ClassFile& cf,
+                               const CodeAttribute& codeAttr) {
+            while (!opStack_.empty())
+                opStack_.pop();
 
-    return locals_[index];
-}
+            locals_.clear();
+            locals_.assign(codeAttr.getMaxLocals(), NULL);
 
-void Compiler::compileMethod(Module& module,
-                             const ClassFile& cf,
-                             const Java::Method& method) {
-    using namespace llvm::Java::Opcode;
-
-    DEBUG(std::cerr << "compiling method: " << method.getName()->str() << '\n');
-
-    Function* function =
-        module.getOrInsertFunction(method.getName()->str(), Type::VoidTy, 0);
-
-    const Java::CodeAttribute* codeAttr =
-        Java::getCodeAttribute(method.getAttributes());
-
-    compileMethodInit(*function, cf, *codeAttr);
-
-    // FIXME: this should really be a non-void type when the object
-    // model is finalized
-    const Type* ObjectTy = Type::VoidTy;
-    const Type* ObjectRefTy = PointerType::get(ObjectTy);
-
-    const uint8_t* code = codeAttr->getCode();
-    for (unsigned i = 0; i < codeAttr->getCodeSize(); ++i) {
-        unsigned bcStart = i;
-        bool wide = code[i] == WIDE;
-        i += wide;
-        switch (code[i]) {
-        case ACONST_NULL:
-            opStack_.push(llvm::Constant::getNullValue(ObjectRefTy));
-            break;
-        case ICONST_M1:
-        case ICONST_0:
-        case ICONST_1:
-        case ICONST_2:
-        case ICONST_3:
-        case ICONST_4:
-        case ICONST_5:
-            opStack_.push(ConstantSInt::get(Type::IntTy, code[i]-ICONST_0));
-            break;
-        case LCONST_0:
-        case LCONST_1:
-            opStack_.push(ConstantSInt::get(Type::LongTy, code[i]-LCONST_0));
-            break;
-        case FCONST_0:
-        case FCONST_1:
-        case FCONST_2:
-            opStack_.push(ConstantFP::get(Type::FloatTy, code[i]-FCONST_0));
-            break;
-        case DCONST_0:
-        case DCONST_1:
-            opStack_.push(ConstantFP::get(Type::DoubleTy, code[i]-DCONST_0));
-            break;
-        case BIPUSH: {
-            int imm = readSByte(code, i);
-            opStack_.push(ConstantSInt::get(Type::IntTy, imm));
-            break;
-        }
-        case SIPUSH: {
-            int imm = readSShort(code, i);
-            opStack_.push(ConstantSInt::get(Type::IntTy, imm));
-            break;
-        }
-        case LDC: {
-            unsigned index = readUByte(code, i);
-            // FIXME: load constant from constant pool
-        }
-        case LDC_W: {
-            unsigned index = readUShort(code, i);
-            // FIXME: load constant from constant pool
-        }
-        case LDC2_W: {
-            unsigned index = readUShort(code, i);
-            // FIXME: load constant from constant pool
-        }
-        case ILOAD:
-        case LLOAD:
-        case FLOAD:
-        case DLOAD:
-        case ALOAD: {
-            // FIXME: use opcodes to perform type checking
-            unsigned index = readUByte(code, i);
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            Bytecode2BasicBlockMapper mapper(function, bc2bbMap_, codeAttr);
+            mapper.compute();
         }
-        case ILOAD_0:
-        case ILOAD_1:
-        case ILOAD_2:
-        case ILOAD_3: {
-            unsigned index = code[i] - ILOAD_0;
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        Value* getOrCreateLocal(unsigned index, const Type* type) {
+            if (!locals_[index]) {
+                BasicBlock* entry = bc2bbMap_[0];
+                Instruction* alloc = new AllocaInst(type);
+                locals_[index] = alloc;
+                Instruction* store = new StoreInst(
+                    llvm::Constant::getNullValue(alloc->getType()), alloc);
+                entry->getInstList().push_front(store);
+                entry->getInstList().push_front(alloc);
+            }
+
+            return locals_[index];
         }
-        case LLOAD_0:
-        case LLOAD_1:
-        case LLOAD_2:
-        case LLOAD_3: {
-            unsigned index = code[i] - LLOAD_0;
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+    public:
+        void compileMethod(Module& module,
+                           const ClassFile& cf,
+                           const Method& method) {
+            DEBUG(std::cerr << "compiling method: "
+                  << method.getName()->str() << '\n');
+
+            Function* function =
+                module.getOrInsertFunction(method.getName()->str(),
+                                           Type::VoidTy, 0);
+
+            const Java::CodeAttribute* codeAttr =
+                Java::getCodeAttribute(method.getAttributes());
+
+            compileMethodInit(*function, cf, *codeAttr);
+
+            parse(codeAttr->getCode(), codeAttr->getCodeSize());
         }
-        case FLOAD_0:
-        case FLOAD_1:
-        case FLOAD_2:
-        case FLOAD_3: {
-            unsigned index = code[i] - FLOAD_0;
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_aconst_null(unsigned bcI) {
+            opStack_.push(llvm::Constant::getNullValue(
+                              PointerType::get(getType(REFERENCE))));
         }
-        case DLOAD_0:
-        case DLOAD_1:
-        case DLOAD_2:
-        case DLOAD_3: {
-            unsigned index = code[i] - DLOAD_0;
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_iconst(unsigned bcI, int value) {
+            opStack_.push(ConstantSInt::get(Type::IntTy, value));
         }
-        case ALOAD_0:
-        case ALOAD_1:
-        case ALOAD_2:
-        case ALOAD_3: {
-            unsigned index = code[i] - ALOAD_0;
-            Instruction* in =
-                new LoadInst(getOrCreateLocal(index, ObjectRefTy));
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_lconst(unsigned bcI, long long value) {
+            opStack_.push(ConstantSInt::get(Type::LongTy, value));
         }
-        case IALOAD:
-        case LALOAD:
-        case FALOAD:
-        case DALOAD:
-        case AALOAD:
-        case BALOAD:
-        case CALOAD:
-        case SALOAD:
-            assert(0 && "not implemented");
-        case ISTORE:
-        case LSTORE:
-        case FSTORE:
-        case DSTORE:
-        case ASTORE: {
-            // FIXME: use opcodes to perform type checking
-            unsigned index = readUByte(code, i);
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Instruction* in = new StoreInst(v1, locals_[index]);
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_fconst(unsigned bcI, float value) {
+            opStack_.push(ConstantFP::get(Type::FloatTy, value));
         }
-        case ISTORE_0:
-        case ISTORE_1:
-        case ISTORE_2:
-        case ISTORE_3: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Instruction* in =
-                new StoreInst(v1, locals_[code[i]-ISTORE_0]);
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_dconst(unsigned bcI, double value) {
+            opStack_.push(ConstantFP::get(Type::DoubleTy, value));
         }
-        case LSTORE_0:
-        case LSTORE_1:
-        case LSTORE_2:
-        case LSTORE_3: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Instruction* in =
-                new StoreInst(v1, locals_[code[i]-LSTORE_0]);
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_ldc(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
         }
-        case FSTORE_0:
-        case FSTORE_1:
-        case FSTORE_2:
-        case FSTORE_3: {
-            Value* v1 = opStack_.top(); opStack_.pop();
+
+        void do_load(unsigned bcI, JType type, unsigned index) {
             Instruction* in =
-                new StoreInst(v1, locals_[code[i]-FSTORE_0]);
+                new LoadInst(getOrCreateLocal(index, getType(type)));
             opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            bc2bbMap_[bcI]->getInstList().push_back(in);
         }
-        case DSTORE_0:
-        case DSTORE_1:
-        case DSTORE_2:
-        case DSTORE_3: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Instruction* in =
-                new StoreInst(v1, locals_[code[i]-DSTORE_0]);
-            opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+
+        void do_aload(unsigned bcI, JType type) {
+            assert(0 && "not implemented");
         }
-        case ASTORE_0:
-        case ASTORE_1:
-        case ASTORE_2:
-        case ASTORE_3: {
+
+        void do_store(unsigned bcI, JType type, unsigned index) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Instruction* in =
-                new StoreInst(v1, locals_[code[i]-ASTORE_0]);
+                new StoreInst(v1, getOrCreateLocal(index, getType(type)));
             opStack_.push(in);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            bc2bbMap_[bcI]->getInstList().push_back(in);
         }
-        case IASTORE:
-        case LASTORE:
-        case FASTORE:
-        case DASTORE:
-        case AASTORE:
-        case BASTORE:
-        case CASTORE:
-        case SASTORE:
+
+
+        void do_astore(unsigned bcI, JType type) {
             assert(0 && "not implemented");
-        case POP:
+        }
+
+        void do_pop(unsigned bcI) {
             opStack_.pop();
-            break;
-        case POP2: {
+        }
+
+        void do_pop2(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             if (isOneSlotValue(v1))
                 opStack_.pop();
-            break;
         }
-        case DUP:
+
+        void do_dup(unsigned bcI) {
             opStack_.push(opStack_.top());
-            break;
-        case DUP_X1: {
+        }
+
+        void do_dup_x1(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             opStack_.push(v1);
             opStack_.push(v2);
             opStack_.push(v1);
-            break;
         }
-        case DUP_X2: {
+
+        void do_dup_x2(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             if (isOneSlotValue(v2)) {
@@ -447,9 +272,9 @@
                 opStack_.push(v2);
                 opStack_.push(v1);
             }
-            break;
         }
-        case DUP2: {
+
+        void do_dup2(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             if (isOneSlotValue(v1)) {
                 Value* v2 = opStack_.top(); opStack_.pop();
@@ -462,9 +287,9 @@
                 opStack_.push(v1);
                 opStack_.push(v1);
             }
-            break;
         }
-        case DUP2_X1: {
+
+        void do_dup2_x1(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             if (isOneSlotValue(v1)) {
@@ -480,9 +305,9 @@
                 opStack_.push(v2);
                 opStack_.push(v1);
             }
-            break;
         }
-        case DUP2_X2: {
+
+        void do_dup2_x2(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             if (isOneSlotValue(v1)) {
@@ -518,299 +343,255 @@
                     opStack_.push(v1);
                 }
             }
-            break;
         }
-        case SWAP: {
+
+        void do_swap(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             opStack_.push(v1);
             opStack_.push(v2);
-            break;
         }
-        case IADD:
-        case LADD:
-        case FADD:
-        case DADD: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Add, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case ISUB:
-        case LSUB:
-        case FSUB:
-        case DSUB: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Sub, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case IMUL:
-        case LMUL:
-        case FMUL:
-        case DMUL: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Mul, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case IDIV:
-        case LDIV:
-        case FDIV:
-        case DDIV: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Div, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case IREM:
-        case LREM:
-        case FREM:
-        case DREM: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Rem, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case INEG:
-        case LNEG:
-        case FNEG:
-        case DNEG:
-        case ISHL:
-        case LSHL: {
+
+        void do_add(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Add);
+        }
+
+        void do_sub(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Sub);
+        }
+
+        void do_mul(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Mul);
+        }
+
+        void do_div(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Div);
+        }
+
+        void do_rem(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Rem);
+        }
+
+        void do_neg(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_shl(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             Instruction* in = new ShiftInst(Instruction::Shl, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            opStack_.push(in);
         }
-        case ISHR:
-        case LSHR: {
+
+        void do_shr(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
             Instruction* in = new ShiftInst(Instruction::Shr, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            opStack_.push(in);
         }
-        case IUSHR:
-        case LUSHR: {
+
+        void do_ushr(unsigned bcI) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Instruction* in =
                 new CastInst(v1, v1->getType()->getUnsignedVersion());
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
+            bc2bbMap_[bcI]->getInstList().push_back(in);
             Value* v2 = opStack_.top(); opStack_.pop();
             in = new ShiftInst(Instruction::Shr, in, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            opStack_.push(in);
         }
-        case IAND:
-        case LAND: {
+
+        void do_and(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::And);
+        }
+
+        void do_or(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Or);
+        }
+
+        void do_xor(unsigned bcI) {
+            do_binary_op_common(bcI, Instruction::Xor);
+        }
+
+        void do_binary_op_common(unsigned bcI, Instruction::BinaryOps op) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::And, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            Instruction* in = BinaryOperator::create(op, v1, v2);
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            opStack_.push(in);
         }
-        case IOR:
-        case LOR: {
+
+
+        void do_iinc(unsigned bcI, unsigned index, unsigned amount) {
+            assert(0 && "not implemented");
+        }
+
+        void do_convert(unsigned bcI, JType to) {
             Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Or, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
+            Instruction* in = new CastInst(v1, getType(to));
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            opStack_.push(in);
+        }
+
+        void do_cmp(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_cmpl(unsigned bcI) {
+            assert(0 && "not implemented");
         }
-        case IXOR:
-        case LXOR: {
+
+        void do_cmpg(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_if(unsigned bcI, JSetCC cc, JType type,
+                   unsigned t, unsigned f) {
             Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = BinaryOperator::create(Instruction::Xor, v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            break;
-        }
-        case IINC:
-        case I2L:
-        case I2F:
-        case I2D:
-        case L2I:
-        case L2F:
-        case L2D:
-        case F2I:
-        case F2L:
-        case F2D:
-        case D2I:
-        case D2L:
-        case D2F:
-        case I2B:
-        case I2C:
-        case I2S:
-        case LCMP:
-        case FCMPL:
-        case FCMPG:
-        case DCMPL:
-        case DCMPG:
-            assert(0 && "not implemented");
-        case IFEQ:
-        case IFNE:
-        case IFLT:
-        case IFGE:
-        case IFGT:
-        case IFLE: {
-            static Instruction::BinaryOps java2llvm[] = {
-                Instruction::SetEQ,
-                Instruction::SetNE,
-                Instruction::SetLT,
-                Instruction::SetGE,
-                Instruction::SetGT,
-                Instruction::SetLE,
-            };
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = ConstantSInt::get(Type::IntTy, 0);
-            Instruction* in = new SetCondInst(java2llvm[i-IFEQ], v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            new BranchInst(bc2bbMap_[bcStart + readSShort(code, i)],
-                           bc2bbMap_[i + 1],
-                           bc2bbMap_[bcStart]);
-            break;
-        }
-        case IF_ICMPEQ:
-        case IF_ICMPNE:
-        case IF_ICMPLT:
-        case IF_ICMPGE:
-        case IF_ICMPGT:
-        case IF_ICMPLE: {
-            static Instruction::BinaryOps java2llvm[] = {
-                Instruction::SetEQ,
-                Instruction::SetNE,
-                Instruction::SetLT,
-                Instruction::SetGE,
-                Instruction::SetGT,
-                Instruction::SetLE,
-            };
+            Value* v2 = llvm::Constant::getNullValue(getType(type));
+            Instruction* in = new SetCondInst(getSetCC(cc), v1, v2);
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            new BranchInst(bc2bbMap_[t],
+                           bc2bbMap_[f],
+                           bc2bbMap_[bcI]);
+        }
+
+        void do_ifcmp(unsigned bcI, JSetCC cc,
+                      unsigned t, unsigned f) {
             Value* v1 = opStack_.top(); opStack_.pop();
             Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = new SetCondInst(java2llvm[i-IF_ICMPEQ], v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            new BranchInst(bc2bbMap_[bcStart + readSShort(code, i)],
-                           bc2bbMap_[i + 1],
-                           bc2bbMap_[bcStart]);
-            break;
-        }
-        case IF_IACMPEQ:
-        case IF_IACMPNE: {
-            static Instruction::BinaryOps java2llvm[] = {
-                Instruction::SetEQ,
-                Instruction::SetNE,
-            };
+            Instruction* in = new SetCondInst(getSetCC(cc), v1, v2);
+            bc2bbMap_[bcI]->getInstList().push_back(in);
+            new BranchInst(bc2bbMap_[t],
+                           bc2bbMap_[f],
+                           bc2bbMap_[bcI]);
+        }
+
+        void do_goto(unsigned bcI, unsigned target) {
+            new BranchInst(bc2bbMap_[target], bc2bbMap_[bcI]);
+        }
+
+        void do_jsr(unsigned bcI, unsigned target) {
+            assert(0 && "not implemented");
+        }
+
+        void do_ret(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_switch(unsigned bcI,
+                       unsigned defTarget,
+                       const SwitchCases& sw) {
             Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = opStack_.top(); opStack_.pop();
-            Instruction* in = new SetCondInst(java2llvm[i-IF_IACMPEQ], v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            new BranchInst(bc2bbMap_[bcStart + readSShort(code, i)],
-                           bc2bbMap_[i + 1],
-                           bc2bbMap_[bcStart]);
-            break;
-        }
-        case GOTO:
-            new BranchInst(bc2bbMap_[bcStart + readSShort(code, i)]);
-            break;
-        case JSR:
-        case RET:
-            assert(0 && "not implemented");
-        case TABLESWITCH: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            skipPadBytes(code, i);
-            int def = readSInt(code, i);
-            int low = readSInt(code, i);
-            int high = readSInt(code, i);
-            SwitchInst* in =
-                new SwitchInst(v1, bc2bbMap_[bcStart + def],bc2bbMap_[bcStart]);
-            while (low <= high)
-                in->addCase(ConstantSInt::get(Type::IntTy, low++),
-                            bc2bbMap_[bcStart + readSInt(code, i)]);
-            break;
-        }
-        case LOOKUPSWITCH: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            skipPadBytes(code, i);
-            int def = readSInt(code, i);
-            unsigned pairCount = readUInt(code, i);
             SwitchInst* in =
-                new SwitchInst(v1, bc2bbMap_[bcStart + def],bc2bbMap_[bcStart]);
-            while (pairCount--)
-                in->addCase(ConstantSInt::get(Type::IntTy, readSInt(code, i)),
-                           bc2bbMap_[bcStart + readSInt(code, i)]);
-            break;
-        }
-        case IRETURN:
-        case LRETURN:
-        case FRETURN:
-        case DRETURN:
-        case ARETURN: {
-            Value* v1 = opStack_.top(); opStack_.pop();
-            new ReturnInst(v1, bc2bbMap_[bcStart]);
-            break;
-        }
-        case RETURN:
-            new ReturnInst(NULL, bc2bbMap_[bcStart]);
-            break;
-        case GETSTATIC:
-        case PUTSTATIC:
-        case GETFIELD:
-        case PUTFIELD:
-        case INVOKEVIRTUAL:
+                new SwitchInst(v1, bc2bbMap_[defTarget], bc2bbMap_[bcI]);
+            for (unsigned i = 0; i < sw.size(); ++i)
+                in->addCase(ConstantSInt::get(Type::IntTy, sw[i].first),
+                            bc2bbMap_[sw[i].second]);
+        }
+
+        void do_return(unsigned bcI) {
+            Value* v1 = opStack_.top(); opStack_.pop();
+            new ReturnInst(v1, bc2bbMap_[bcI]);
+        }
+
+        void do_return_void(unsigned bcI) {
+            new ReturnInst(NULL, bc2bbMap_[bcI]);
+        }
+
+        void do_getstatic(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_putstatic(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_getfield(unsigned bcI, unsigned index) {
             assert(0 && "not implemented");
-        case INVOKESPECIAL: {
-            unsigned index = readUShort(code, i);
+        }
+
+        void do_putfield(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_invokevirtual(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_invokespecial(unsigned bcI, unsigned index) {
             DEBUG(std::cerr << "ignoring INVOKESPECIAL\n");
-            break;
         }
-        case INVOKESTATIC:
-        case INVOKEINTERFACE:
-        case XXXUNUSEDXXX:
-        case NEW:
-        case NEWARRAY:
-        case ANEWARRAY:
-        case ARRAYLENGTH:
-        case ATHROW:
-        case CHECKCAST:
-        case INSTANCEOF:
-        case MONITORENTER:
-        case MONITOREXIT:
-//      case WIDE:
-        case MULTIANEWARRAY:
-            assert(0 && "not implemented");
-        case IFNULL:
-        case IFNONNULL: {
-            static Instruction::BinaryOps java2llvm[] = {
-                Instruction::SetEQ,
-                Instruction::SetNE,
-            };
-            Value* v1 = opStack_.top(); opStack_.pop();
-            Value* v2 = llvm::Constant::getNullValue(ObjectRefTy);
-            Instruction* in = new SetCondInst(java2llvm[i-IFNULL], v1, v2);
-            bc2bbMap_[bcStart]->getInstList().push_back(in);
-            new BranchInst(bc2bbMap_[bcStart + readSShort(code, i)],
-                           bc2bbMap_[i + 1],
-                           bc2bbMap_[bcStart]);
-            break;
-        }
-        case GOTO_W:
-            new BranchInst(bc2bbMap_[bcStart + readSInt(code, i)]);
-            break;
-        case JSR_W:
-            assert(0 && "not implemented");
-        case BREAKPOINT:
-        case IMPDEP1:
-        case IMPDEP2:
-        case NOP:
-            break;
+
+        void do_invokestatic(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
         }
-    }
+
+        void do_invokeinterface(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_new(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_newarray(unsigned bcI, JType type) {
+            assert(0 && "not implemented");
+        }
+
+        void do_anewarray(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_arraylength(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_athrow(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_checkcast(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_instanceof(unsigned bcI, unsigned index) {
+            assert(0 && "not implemented");
+        }
+
+        void do_monitorenter(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_monitorexit(unsigned bcI) {
+            assert(0 && "not implemented");
+        }
+
+        void do_multianewarray(unsigned bcI,
+                               unsigned index,
+                               unsigned dims) {
+            assert(0 && "not implemented");
+        }
+
+    private:
+        OperandStack opStack_;
+        Locals locals_;
+        BC2BBMap bc2bbMap_;
+    };
+
+} } } // namespace llvm::Java::
+
+Compiler::Compiler()
+    : compilerImpl_(new CompilerImpl())
+{
+
+}
+
+Compiler::~Compiler()
+{
+    delete compilerImpl_;
 }
 
 Module* Compiler::compile(const ClassFile& cf)
@@ -823,7 +604,7 @@
     const Java::Methods& methods = cf.getMethods();
     for (Java::Methods::const_iterator
              i = methods.begin(), e = methods.end(); i != e; ++i)
-        compileMethod(*module, cf, **i);
+        compilerImpl_->compileMethod(*module, cf, **i);
 
     return module;
 }





More information about the llvm-commits mailing list