Package org.trifort.rootbeer.generate.opencl.fields

Source Code of org.trifort.rootbeer.generate.opencl.fields.OpenCLField

/*
* Copyright 2012 Phil Pratt-Szeliga and other contributors
* http://chirrup.org/
*
* See the file LICENSE for copying permission.
*/

package org.trifort.rootbeer.generate.opencl.fields;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.trifort.rootbeer.configuration.Configuration;
import org.trifort.rootbeer.generate.bytecode.StaticOffsets;
import org.trifort.rootbeer.generate.opencl.OpenCLClass;
import org.trifort.rootbeer.generate.opencl.OpenCLScene;
import org.trifort.rootbeer.generate.opencl.OpenCLType;
import org.trifort.rootbeer.generate.opencl.fields.CompositeField;
import org.trifort.rootbeer.generate.opencl.fields.OffsetCalculator;
import org.trifort.rootbeer.generate.opencl.tweaks.Tweaks;

import soot.Local;
import soot.Modifier;
import soot.Scene;
import soot.SootClass;
import soot.SootField;
import soot.Type;
import soot.Value;
import soot.jimple.toolkits.typing.fast.Integer127Type;
import soot.options.Options;
import soot.rbclassload.FieldSignatureUtil;
import soot.rbclassload.RootbeerClassLoader;

public class OpenCLField {
  private final SootField m_sootField;
  private final SootClass m_sootClass;
  private boolean m_cloned;
  private OpenCLField m_cloneSource;
  private Map<Integer, List<SootClass>> m_offsets;

  public OpenCLField(SootField soot_field, SootClass soot_class) {
    m_sootField = soot_field;
    m_sootClass = soot_class;
    m_cloned = false;   
  }
 
  public void setClone(OpenCLField source){
    m_cloned = true;
    m_cloneSource = source;
  }
 
  public boolean isCloned(){
    return m_cloned;
 
 
  public OpenCLField getCloneSource(){
    return m_cloneSource;
  }
 
  public String getName(){
    return m_sootField.getName();
  }

  public SootField getSootField(){
    return m_sootField;
  }

  private String getFullName(){
    FieldSignatureUtil util = new FieldSignatureUtil();
    util.parse(m_sootField.getSignature());
    SootField real_field = util.getSootField();
    OpenCLClass ocl_class = OpenCLScene.v().getOpenCLClass(real_field.getDeclaringClass());
    return ocl_class.getName()+"_"+getName();
  }
 
  public OpenCLType getClassType(){
    Type soot_type = m_sootClass.getType();
    return new OpenCLType(soot_type);
  }

  public OpenCLType getType(){
    Type soot_type = m_sootField.getType();
    return new OpenCLType(soot_type);
  }

  private List<String> getDecls(){
    List<String> ret = new ArrayList<String>();
    String type_string = getType().getCudaTypeString();
    String device_function_qual = Tweaks.v().getDeviceFunctionQualifier();
    String address_qual = Tweaks.v().getGlobalAddressSpaceQualifier();
    if(m_sootField.isStatic() == false){
      //instance getter
      ret.add(device_function_qual+" "+type_string+" instance_getter_"+getFullName()+"(int thisref, int * exception)");
      //instance setter
      ret.add(device_function_qual+" void instance_setter_"+getFullName()+"(int thisref, "+type_string+" parameter0, int * exception)");
    } else {
      //static getter
      ret.add(device_function_qual+" "+type_string+" static_getter_"+getFullName()+"(int * exception)");
      //static setter
      ret.add(device_function_qual+" void static_setter_"+getFullName()+"("+type_string+" parameter0, int * expcetion)");
    }
    return ret;
  }

  public String getGetterSetterPrototypes(){
    StringBuilder ret = new StringBuilder();
    List<String> decls = getDecls();
    for(String decl : decls){
      ret.append(decl+";\n");
    }
    return ret.toString();
  }
 
  public int getSize(){
    return getType().getSize();
  }

  private void calculateOffsets(CompositeField composite){   
    OffsetCalculator calc = new OffsetCalculator(composite);
    m_offsets = new TreeMap<Integer, List<SootClass>>();
    for(SootClass sclass : composite.getClasses()){
      int field_offset = calc.getOffset(this, sclass);
      List<SootClass> classes;
      if(m_offsets.containsKey(field_offset)){
        classes = m_offsets.get(field_offset);
      } else {
        classes = new ArrayList<SootClass>();
        m_offsets.put(field_offset, classes);
      }
      classes.add(sclass);
    }
  }
 
  private int getOnlyOffset(){
    Iterator<Integer> iter = m_offsets.keySet().iterator();
    while(iter.hasNext()){
      int ret = iter.next();
      return ret;
    }
    return -1;
  }
 
  private String getGetterSetterBodiesInstance(CompositeField composite, boolean writable,
    FieldTypeSwitch type_switch){
   
    StringBuilder ret = new StringBuilder();
    List<String> decls = getDecls();
    String address_qual = Tweaks.v().getGlobalAddressSpaceQualifier();
   
    String cast_string = getCastString();
   
    calculateOffsets(composite);
   
    String prefix = Options.v().rbcl_remap_prefix();   
    if(Options.v().rbcl_remap_all() == false){
      prefix = "";
    }
    SootClass null_cls = Scene.v().getSootClass(prefix+"java.lang.NullPointerException");
    int null_num = RootbeerClassLoader.v().getClassNumber(null_cls);
   
    //instance getter
    ret.append(decls.get(0)+"{\n");
    int field_offset = getOnlyOffset();
    //ret.append("if("+thisref+" & 0x1000000000000000L){\n");
    //ret.append("  thisref &= 0x0fffffffffffffffL;\n");
    //ret.append("  thisref += "+field_offset+";\n");
    //ret.append("  return org_trifort_cache_get_"+type+"(thisref);\n");
    //ret.append("} else {\n");  
    if(composite.getClasses().size() != 1){
      ret.append("GC_OBJ_TYPE_TYPE derived_type;\n");
      ret.append("int offset;\n");
    }
    ret.append(address_qual+" char * thisref_deref;\n");
    if(Configuration.compilerInstance().getExceptions()){
      ret.append("if(thisref == -1){\n");
      ret.append("  *exception = "+null_num+";\n");
      ret.append("  return 0;\n");
      ret.append("}\n");
    }
    ret.append("thisref_deref = org_trifort_gc_deref(thisref);\n");
    if(composite.getClasses().size() == 1){
      SootClass sclass = composite.getClasses().get(0);
      ret.append("return *(("+address_qual+" "+cast_string+" *) &thisref_deref["+Integer.toString(field_offset)+"]);\n");
    } else {
      ret.append("derived_type = org_trifort_gc_get_type(thisref_deref);\n");
      ret.append("offset = "+type_switch.typeSwitchName(m_offsets)+"(derived_type);\n");
      ret.append("return *(("+address_qual+" "+cast_string+" *) &thisref_deref[offset]);\n");
    }
    //ret.append("}\n");
    ret.append("}\n");
    //instance setter
    ret.append(decls.get(1)+"{\n");
    if(composite.getClasses().size() != 1){
      ret.append("GC_OBJ_TYPE_TYPE derived_type;\n");
      ret.append("int offset;\n");
    }
    ret.append(address_qual+" char * thisref_deref;\n");
    if(Configuration.compilerInstance().getExceptions()){
      ret.append("if(thisref == -1){\n");
      ret.append("  *exception = "+null_num+";\n");
      ret.append("  return;\n");
      ret.append("}\n");
    }
    ret.append("thisref_deref = org_trifort_gc_deref(thisref);\n");   
    if(composite.getClasses().size() == 1){
      ret.append("*(("+address_qual+" "+cast_string+" *) &thisref_deref["+Integer.toString(field_offset)+"]) = parameter0;\n");
    } else {
      ret.append("derived_type = org_trifort_gc_get_type(thisref_deref);\n");
      ret.append("offset = "+type_switch.typeSwitchName(m_offsets)+"(derived_type);\n");    
      ret.append("*(("+address_qual+" "+cast_string+" *) &thisref_deref[offset]) = parameter0;\n");
    }
    ret.append("}\n");
   
    return ret.toString();
  }
 
  private String getGetterSetterBodiesStatic() {
    StringBuilder ret = new StringBuilder();
    List<String> decls = getDecls();
    String address_qual = Tweaks.v().getGlobalAddressSpaceQualifier();
    StaticOffsets static_offsets = new StaticOffsets();
    int offset = static_offsets.getIndex(this);
   
    String cast_string = getCastString();
   
    ret.append(decls.get(0)+"{\n");
    ret.append(address_qual+" char * thisref_deref = org_trifort_gc_deref(0);\n");
    ret.append("return *(("+address_qual+" "+cast_string+" *) &thisref_deref["+offset+"]);\n");
    ret.append("}\n");
   
    ret.append(decls.get(1)+"{\n");   
    ret.append(address_qual+" char * thisref_deref = org_trifort_gc_deref(0);\n");
    ret.append("*(("+address_qual+" "+cast_string+" *) &thisref_deref["+offset+"]) = parameter0;\n");
    ret.append("}\n");
    return ret.toString();
  }
 
  public String getGetterSetterBodies(CompositeField composite, boolean writable,
    FieldTypeSwitch type_switch){
   
    if(m_sootField.isStatic()){
      return getGetterSetterBodiesStatic();
    } else {
      return getGetterSetterBodiesInstance(composite, writable, type_switch);
    }   
  }
 
  private String checkAlignmentString(int field_offset){
    String ret = "";
    ret += "int addr = thisref_deref + "+field_offset+";\n";
    ret += "if(addr % "+getSize()+" != 0){\n";
    ret += "  printf(\"misaligned field: "+m_sootField.toString()+"\\n\");\n";
    ret += "}\n";
    return ret;
  }
 
  public String getStaticGetterInvoke(){
    return "static_getter_"+getFullName()+"(exception)";
  }

  public String getStaticSetterInvoke(){
    return "static_setter_"+getFullName()+"(";
  }

  public String getInstanceGetterInvoke(Value base){
    if(base instanceof Local == false)
      throw new UnsupportedOperationException("how do we handle when a base is not a loca?");
    Local local = (Local) base;
    return "instance_getter_"+getFullName()+"("+local.getName()+", exception)";
  }

  public String getInstanceSetterInvoke(Value base){
    if(base instanceof Local == false)
      throw new UnsupportedOperationException("how do we handle when a base is not a loca?");
    Local local = (Local) base;
    return "instance_setter_"+getFullName()+"("+local.getName()+", ";
  }
 
  public String getInstanceSetterInvokeWithoutThisref(){
    return "instance_setter_"+getFullName()+"(";
  }

  @Override
  public String toString(){
    return getType().getDerefString()+" "+getName();
  }

  @Override
  public boolean equals(Object o){
    if(o instanceof OpenCLField == false)
      return false;
    OpenCLField other = (OpenCLField) o;
    if(m_sootField.equals(other.m_sootField) && m_sootClass.equals(other.m_sootClass))
      return true;
    return false;
  }

  @Override
  public int hashCode() {
    int hash = 7;
    hash = 37 * hash + (this.m_sootField != null ? this.m_sootField.hashCode() : 0);
    hash = 37 * hash + (this.m_sootClass != null ? this.m_sootClass.hashCode() : 0);
    return hash;
  }

  public boolean isInstance() {
    if(m_sootField.isStatic())
      return false;
    return true;
  }

  private String getCastString() {
    String ret = getType().getCudaTypeString();
    return ret;
  }

  public boolean isFinal() {
    return m_sootField.isFinal();
  }
}
TOP

Related Classes of org.trifort.rootbeer.generate.opencl.fields.OpenCLField

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.