Package org.jnode.vm.compiler.ir

Source Code of org.jnode.vm.compiler.ir.IRTest

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.compiler.ir;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.jnode.assembler.x86.X86Assembler;
import org.jnode.assembler.x86.X86BinaryAssembler;
import org.jnode.assembler.x86.X86Constants;
import org.jnode.assembler.x86.X86Register;
import org.jnode.assembler.x86.X86TextAssembler;
import org.jnode.vm.VmImpl;
import org.jnode.vm.VmSystemClassLoader;
import org.jnode.vm.bytecode.BytecodeParser;
import org.jnode.vm.classmgr.VmByteCode;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.compiler.CompiledMethod;
import org.jnode.vm.compiler.EntryPoints;
import org.jnode.vm.compiler.ir.quad.Quad;
import org.jnode.vm.facade.TypeSizeInfo;
import org.jnode.vm.facade.VmUtils;
import org.jnode.vm.x86.VmX86Architecture32;
import org.jnode.vm.x86.X86CpuID;
import org.jnode.vm.x86.compiler.X86CompilerHelper;
import org.jnode.vm.x86.compiler.l2.X86CodeGenerator;
import org.jnode.vm.x86.compiler.l2.X86Level2Compiler;
import org.jnode.vm.x86.compiler.l2.X86StackFrame;

/**
* @author Madhu Siddalingaiah
* @author Levente S\u00e1ntha
*/
public class IRTest {
    public static void main(String args[]) throws SecurityException, IOException, ClassNotFoundException,
        InstantiationException {
//        System.in.read();
        X86CpuID cpuId = X86CpuID.createID("p5");
        boolean binary = false;

        String className = "org.jnode.vm.compiler.ir.PrimitiveTest";
//        String className = "org.jnode.games.tetris.Tetris";
        if (args.length > 0) {
            String arg0 = args[0];
            if ("-b".equals(arg0)) {
                binary = true;
                if (args.length > 1) {
                    className = args[1];
                }
            } else {
                className = arg0;
            }
        }

        if (binary) {
            X86BinaryAssembler os = new X86BinaryAssembler(cpuId, X86Constants.Mode.CODE32, 0);
            generateCode(os, className);
            FileOutputStream fos = new FileOutputStream("test.bin");
            os.writeTo(fos);
            fos.close();
        } else {
            X86TextAssembler tos =
                new X86TextAssembler(new OutputStreamWriter(System.out), cpuId, X86Constants.Mode.CODE32);
            generateCode(tos, className);
            tos.flush();
        }

/*
        BytecodeViewer bv = new BytecodeViewer();
        BytecodeParser.parse(code, bv);

        // System.out.println(cfg.toString());
        // System.out.println();

        boolean printDeadCode = false;
        boolean printDetail = false;
        IRBasicBlock currentBlock = null;
        for (int i=0; i<n; i+=1) {
            Quad quad = (Quad) quads.get(i);
            if (currentBlock != quad.getBasicBlock()) {
                currentBlock = quad.getBasicBlock();
                System.out.println();
                System.out.println(currentBlock);
            }
            if (printDeadCode && quad.isDeadCode()) {
                if (printDetail) {
                    printQuadDetail(quad);
                }
                System.out.println(quad);
            }
            if (!quad.isDeadCode()) {
                if (printDetail) {
                    printQuadDetail(quad);
                }
                System.out.println(quad);
            }
        }

        System.out.println();
        System.out.println("Live ranges:");
        n = lv.size();
        for (int i=0; i<n; i+=1) {
            System.out.println(liveRanges[i]);
        }
*/
    }

    private static void generateCode(X86Assembler os, String className)
        throws MalformedURLException, ClassNotFoundException, InstantiationException {
        //VmByteCode code = loadByteCode(className, "discriminant");
        //VmByteCode code = loadByteCode(className, "arithOptIntx");
        //VmByteCode code = loadByteCode(className, "simpleWhile");
        //VmByteCode code = loadByteCode(className, "terniary2");
//        VmByteCode code = loadByteCode(className, "trivial1");
//        VmByteCode code = loadByteCode(className, "discriminant");
//        VmByteCode code = loadByteCode(className, "arithOptLoop");

        //VmByteCode code = loadByteCode(className, "discriminant");
        //VmByteCode code = loadByteCode(className, "arithOptIntx");
        //VmByteCode code = loadByteCode(className, "simpleWhile");
        //VmByteCode code = loadByteCode(className, "terniary2");

        VmX86Architecture32 arch = new VmX86Architecture32();
        VmSystemClassLoader loader = new VmSystemClassLoader(new URL[]{
            new File("core/build/classes").toURL(),
            new File("distr/build/classes").toURL(),
            new File("local/classlib").toURL()
        }, arch);
        new VmImpl("?", arch, loader.getSharedStatics(), true, loader, null);
        VmType.initializeForBootImage(loader);
        VmType<?> type = loader.loadClass(className, true);
        VmMethod arithMethod = null;
        int nMethods = type.getNoDeclaredMethods();
        for (int i = 0; i < nMethods; i += 1) {
            VmMethod method1 = type.getDeclaredMethod(i);
            if ("terniary22".equals(method1.getName())) {
//            if ("darken".equals(method1.getName())) {
                arithMethod = method1;
                break;
            }
        }
        VmMethod method = arithMethod;
        VmByteCode code = method.getBytecode();
        //VmByteCode code = loadByteCode(className, "appel");

        EntryPoints context = new EntryPoints(loader, VmUtils.getVm().getHeapManager(), 1);
        X86CompilerHelper helper = new X86CompilerHelper(os, null, context, true);
        CompiledMethod cm = new CompiledMethod(1);
        TypeSizeInfo typeSizeInfo = loader.getArchitecture().getTypeSizeInfo();
        helper.setMethod(method);
        X86StackFrame stackFrame = new X86StackFrame(os, helper, method, context, cm);
        X86CodeGenerator x86cg = new X86CodeGenerator(method, os, code.getLength(), typeSizeInfo, stackFrame);

        generateCode(os, code, x86cg, stackFrame, arithMethod, typeSizeInfo);


//        X86CodeGenerator x86cg = null;//new X86CodeGenerator(os, code.getLength());
//
//        generateCode(os, code, x86cg);
    }

    private static <T extends X86Register> void generateCode(X86Assembler os, VmByteCode code, CodeGenerator<T> cg,
                                                             X86StackFrame stackFrame, VmMethod arithMethod,
                                                             TypeSizeInfo typeSizeInfo)
        throws MalformedURLException, ClassNotFoundException {
        IRControlFlowGraph<T> cfg = new IRControlFlowGraph<T>(code);

        //BytecodeViewer bv = new BytecodeViewer();
        //BytecodeParser.parse(code, bv);

        //System.out.println(cfg.toString());
        //System.out.println();

        //System.out.println(cfg);
        IRGenerator<T> irg = new IRGenerator<T>(cfg);
        BytecodeParser.parse(code, irg);

        X86Level2Compiler.initMethodArguments(arithMethod, stackFrame, typeSizeInfo, irg);

        cfg.constructSSA();
        printCFG(cfg, "Constructed SSA");

        cfg.optimize();
        printCFG(cfg, "Optimized SSA (pass 2)");

        cfg.removeUnusedVars();
        printCFG(cfg, "Unused vars removed SSA");

        cfg.deconstrucSSA();
        cfg.fixupAddresses();
        printCFG(cfg, "Deconstructed SSA");

//        removeUnusedVars(cfg);
//        printCFG(cfg, "Unused vars removed SSA");

        cfg.fixupAddresses();
        List liveVariables = cfg.computeLiveVariables();
//        System.out.println();

//        cfg.optimize(liveVariables.values());
//        printCFG(cfg, "Optimized SSA (pass 3)");

        System.out.println("Live ranges:");
        LiveRange<?>[] liveRanges = X86Level2Compiler.getLiveRanges(liveVariables);

        LinearScanAllocator<?> lsa = X86Level2Compiler.allocate(liveRanges);

        for (LiveRange range : liveRanges) {
            System.out.println(range);
        }

        System.out.println();

        X86Level2Compiler.generateCode(cg, cfg, irg, lsa);

        // TODO
        // 1. Fix method argument location, allocator leaves it null and breaks
        // 2. Many necessary operations are not implemented in the code generator
        // 3. Do something about unused phi nodes, they just waste space right now

//        BootableArrayList quads = irg.getQuadList();
//        int n = quads.size();
//        BootableHashMap liveVariables = new BootableHashMap();
//        for (int i=0; i<n; i+=1) {
//            Quad quad = (Quad) quads.get(i);
////            System.out.println(quad);
//            quad.doPass2(liveVariables);
//            System.out.println(quad);
//        }

//        Collection lv = liveVariables.values();
//        n = lv.size();
//        LiveRange[] liveRanges = new LiveRange[n];
//        Iterator it = lv.iterator();
//        for (int i=0; i<n; i+=1) {
//            Variable v = (Variable) it.next();
//            liveRanges[i] = new LiveRange(v);
//            // System.out.println("Live range: " + liveRanges[i]);
//        }
//        Arrays.sort(liveRanges);
//        System.out.println(Arrays.asList(liveRanges));
//        LinearScanAllocator lsa = new LinearScanAllocator(liveRanges);
//        lsa.allocate();
//
//        x86cg.setArgumentVariables(irg.getVariables(), irg.getNoArgs());
//        x86cg.setSpilledVariables(lsa.getSpilledVariables());
//        x86cg.emitHeader();
//
//        n = quads.size();
//        for (int i=0; i<n; i+=1) {
//            Quad quad = (Quad) quads.get(i);
//            if (!quad.isDeadCode()) {
//                quad.generateCode(x86cg);
//            }
//        }
    }

    private static <T extends X86Register> void printCFG(IRControlFlowGraph<T> cfg, String x) {
        System.out.println(x);
        for (IRBasicBlock<T> b : cfg) {
            System.out.println(b + ", stackOffset = " + b.getStackOffset());
            for (Quad<T> q : b.getQuads()) {
                if (!q.isDeadCode()) {
                    System.out.println(q);
                }
            }
        }
        System.out.println();
    }

    private static VmByteCode loadByteCode(String className, String methodName)
        throws MalformedURLException, ClassNotFoundException, InstantiationException {
        //VmSystemClassLoader vmc = new VmSystemClassLoader(new File(".").toURL(), new VmX86Architecture32());
        VmX86Architecture32 arch = new VmX86Architecture32();
        VmSystemClassLoader vmc = new VmSystemClassLoader(new URL[]{
            new File("core/build/classes").toURL(),
            new File("local/classlib").toURL()
        }, arch);
        new VmImpl("?", arch, vmc.getSharedStatics(), true, vmc, null);
        VmType<?> type = vmc.loadClass(className, true);
        VmMethod arithMethod = null;
        int nMethods = type.getNoDeclaredMethods();
        for (int i = 0; i < nMethods; i += 1) {
            VmMethod method = type.getDeclaredMethod(i);
            if (methodName.equals(method.getName())) {
                arithMethod = method;
                break;
            }
        }
        VmByteCode code = arithMethod.getBytecode();
        return code;
    }

    public static <T> void printQuadDetail(Quad<T> quad) {
        System.out.print(quad.getBasicBlock());
        System.out.print(" ");
        Variable[] vars = quad.getBasicBlock().getVariables();
        System.out.print("[");
        for (Variable var : vars) {
            System.out.print(var);
            System.out.print(",");
        }
        System.out.print("] ");
        if (quad.isDeadCode()) {
            System.out.print("(dead) ");
        }
    }
}
TOP

Related Classes of org.jnode.vm.compiler.ir.IRTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.