[vmkit-commits] [vmkit] r199656 - Add the lowering pass for MMTk.

Gael Thomas gael.thomas at lip6.fr
Mon Jan 20 05:35:01 PST 2014


Author: gthomas
Date: Mon Jan 20 07:35:01 2014
New Revision: 199656

URL: http://llvm.org/viewvc/llvm-project?rev=199656&view=rev
Log:
Add the lowering pass for MMTk.

Added:
    vmkit/branches/mcjit/lib/mmtk/magic/   (with props)
    vmkit/branches/mcjit/lib/mmtk/magic/Makefile
    vmkit/branches/mcjit/lib/mmtk/magic/lower-java-runtime.cc
    vmkit/branches/mcjit/lib/mmtk/magic/lower-magic.cc
Modified:
    vmkit/branches/mcjit/Makefile
    vmkit/branches/mcjit/Makefile.rules
    vmkit/branches/mcjit/lib/mmtk/Makefile

Modified: vmkit/branches/mcjit/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/Makefile?rev=199656&r1=199655&r2=199656&view=diff
==============================================================================
--- vmkit/branches/mcjit/Makefile (original)
+++ vmkit/branches/mcjit/Makefile Mon Jan 20 07:35:01 2014
@@ -5,6 +5,6 @@
 
 LEVEL := .
 
-DIRS := tools/vmkit-extract lib tools/j3 
+DIRS := tools/vmkit-extract lib tools/j3 lib/mmtk/
 
 include $(LEVEL)/Makefile.rules

Modified: vmkit/branches/mcjit/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/Makefile.rules?rev=199656&r1=199655&r2=199656&view=diff
==============================================================================
--- vmkit/branches/mcjit/Makefile.rules (original)
+++ vmkit/branches/mcjit/Makefile.rules Mon Jan 20 07:35:01 2014
@@ -60,49 +60,38 @@ SHFLAGS=-lpthread -ldl -lz -lncurses -fr
 ###############################################################################
 #   Targets
 ###############################################################################
-.PHONY: all tidy clean confclean
+.PHONY: all all-recursive clean clean-recursive clean-local tidy confclean check
 .SECONDARY:
 .SUFFIXES:
 
-all::
-
-check::
-	$(Echo) "---- building with: "
-	$(Echo) "  PROJ_SRC_ROOT: $(PROJ_SRC_ROOT)"
-	$(Echo) "  PROJ_OBJ_ROOT: $(PROJ_OBJ_ROOT)"
-	$(Echo) "  SHFLAGS: $(SHFLAGS)"
-	$(Echo) "  EXEEXT: $(EXEEXT)"
-	$(Echo) "  SHLIBEXT: $(SHLIBEXT)"
-	$(Echo) "  OPTIMIZED: $(OPTIMIZED)"
-	$(Echo) "  DEBUG: $(DEBUG)"
-	$(Echo) "  ASSERT: $(ASSERT)"
-	$(Echo) "  CONFIG_FILES: $(CONFIG_FILES)"
-	$(Echo) "  CONFIG_HEADERS: $(CONFIG_HEADERS)"
-	$(Echo) "  BUILD_NAME: $(BUILD_NAME)"
-	$(Echo) "  CLANG: $(CLANG)"
-	$(Echo) "  CLANGXX: $(CLANGXX)"
-	$(Echo) "  LLC: $(LLC)"
-	$(Echo) "  LOPT: $(LOPT)"
-
 ###############################################################################
 #   Recursive target managment
 ###############################################################################
 RECURSIVE_TARGETS=all clean
 
 define do_sub_target
-$1::
+$1-recursive::
   #$(Echo) "Entering directory $$(PROF)/$2"
 	$(Verb) +$(MAKE) $(SUB_OPT) -C $2 $1 PROF=$(PROF)/$2; \
 		if [ $$$$? != 0 ]; then echo "$$(EchoMsg) abort with errors in $$(PROF)/$2"; exit 1; fi
 endef
 
-$(foreach target,$(RECURSIVE_TARGETS),$(foreach dir,$(DIRS),$(eval $(call do_sub_target,$(target),$(dir)))))
+define do_recursive_target
+$1:
+	 $(Verb) +$(MAKE) $(SUB_OPT) $1-recursive 
+	 $(Verb) +$(MAKE) $1-local
+$1-recursive::
+$1-local::
+$$(foreach dir,$$(DIRS),$$(eval $$(call do_sub_target,$1,$$(dir))))
+endef
+
+$(foreach target,$(RECURSIVE_TARGETS),$(eval $(call do_recursive_target,$(target))))
 
 tidy:
 	$(Echo) "Cleaning temporary files"
 	$(Verb) find $(PROJ_OBJ_ROOT) \( -iname "*~" -o -iname "\#*" \) -exec rm -f {} \;
 
-clean::
+clean-local::
 	$(Echo) "Cleaning compilation files"
 	$(Verb) rm -Rf $(BUILD_DIR)
 
@@ -113,6 +102,24 @@ confclean: clean
 	$(Verb) rm -Rf $(PROJ_OBJ_ROOT)/config.status $(PROJ_OBJ_ROOT)/config.log
 	$(Verb) rm -Rf $(PROJ_OBJ_ROOT)/autoconf/autom4te.cache $(PROJ_OBJ_ROOT)/autoconf/configure.bak
 
+check::
+	$(Echo) "---- building with: "
+	$(Echo) "  PROJ_SRC_ROOT: $(PROJ_SRC_ROOT)"
+	$(Echo) "  PROJ_OBJ_ROOT: $(PROJ_OBJ_ROOT)"
+	$(Echo) "  SHFLAGS: $(SHFLAGS)"
+	$(Echo) "  EXEEXT: $(EXEEXT)"
+	$(Echo) "  SHLIBEXT: $(SHLIBEXT)"
+	$(Echo) "  OPTIMIZED: $(OPTIMIZED)"
+	$(Echo) "  DEBUG: $(DEBUG)"
+	$(Echo) "  ASSERT: $(ASSERT)"
+	$(Echo) "  CONFIG_FILES: $(CONFIG_FILES)"
+	$(Echo) "  CONFIG_HEADERS: $(CONFIG_HEADERS)"
+	$(Echo) "  BUILD_NAME: $(BUILD_NAME)"
+	$(Echo) "  CLANG: $(CLANG)"
+	$(Echo) "  CLANGXX: $(CLANGXX)"
+	$(Echo) "  LLC: $(LLC)"
+	$(Echo) "  LOPT: $(LOPT)"
+
 ###############################################################################
 #   Build system managment
 ###############################################################################
@@ -158,7 +165,7 @@ ifdef MODULE
 
 GEN_MODULE=$(LIB_DIR)/$(MODULE)
 
-all:: $(LIB_DIR)/.dir $(GEN_MODULE).a $(GEN_MODULE).bc
+all-local:: $(LIB_DIR)/.dir $(GEN_MODULE).a $(GEN_MODULE).bc
 
 # not used for the moment
 ifdef __EXTRACT__
@@ -249,7 +256,7 @@ TOOL_FLAGS=$(LLVM_LDFLAGS) $(SHFLAGS)
 LDFLAGS=$(SO_LIBS)
 endif
 
-all:: $(TOOL_ALL)
+all-local:: $(TOOL_ALL)
 
 $(TOOL_OUT): $(TOOL_DEP)
 	$(Echo) "Linking '$(notdir $@)'"
@@ -270,7 +277,7 @@ endif
 ###############################################################################
 ifdef LIBRARY
 SONAME=$(LIB_DIR)/$(LIBRARY)
-all:: $(LIB_DIR)/.dir $(SONAME)$(SHLIBEXT)
+all-local:: $(LIB_DIR)/.dir $(SONAME)$(SHLIBEXT)
 
 SO_FILES=$(OBJ_FILES)
 

Modified: vmkit/branches/mcjit/lib/mmtk/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/mmtk/Makefile?rev=199656&r1=199655&r2=199656&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/mmtk/Makefile (original)
+++ vmkit/branches/mcjit/lib/mmtk/Makefile Mon Jan 20 07:35:01 2014
@@ -5,13 +5,21 @@
 
 LEVEL := ../..
 
-BASE_OBJ_FILES=mmtk-llvm
+DIRS:=magic
+
+BASE_OBJ_FILES=mmtk-lowered
 MODULE=mmtk
 
 include $(LEVEL)/Makefile.rules
 
+MMTK_JAR=$(MMTK_PATH)/mmtk/mmtk.jar 
+LOWER=$(LIB_DIR)/mmtk-pass$(SHLIBEXT)
 J3=$(BIN_DIR)/j3
 
-$(BUILD_DIR)/mmtk-llvm.bc: $(BUILD_DIR)/.dir $(J3) $(SELF)
-	$(Echo) "Generating the llvm bytecode of mmtk"
-	$(Verb) $(J3) -Xaot $@ -cp $(MMTK_PATH)/vmmagic-stub/classes/:$(MMTK_PATH)/options/classes/ -jar $(MMTK_PATH)/mmtk/mmtk.jar 
\ No newline at end of file
+$(BUILD_DIR)/mmtk-lowered.bc: $(BUILD_DIR)/mmtk-bc.bc $(LOWER)
+	$(Echo) "Lowering '$(notdir $<)'"
+	$(Verb) cp $< $@
+
+$(BUILD_DIR)/mmtk-bc.bc: $(MMTK_JAR) $(BUILD_DIR)/.dir $(J3) $(SELF)
+	$(Echo) "Compiling '$(notdir $<)'"
+	$(Verb) $(J3) -Xaot $@ -cp $(MMTK_PATH)/vmmagic-stub/classes/:$(MMTK_PATH)/options/classes/ -jar $(MMTK_JAR)
\ No newline at end of file

Propchange: vmkit/branches/mcjit/lib/mmtk/magic/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jan 20 07:35:01 2014
@@ -0,0 +1 @@
+Debug+Asserts

Added: vmkit/branches/mcjit/lib/mmtk/magic/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/mmtk/magic/Makefile?rev=199656&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/mmtk/magic/Makefile (added)
+++ vmkit/branches/mcjit/lib/mmtk/magic/Makefile Mon Jan 20 07:35:01 2014
@@ -0,0 +1,15 @@
+##===- mmtk/magic/Makefile ---------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+
+LIBRARY=mmtk-pass
+
+include $(LEVEL)/Makefile.rules
+

Added: vmkit/branches/mcjit/lib/mmtk/magic/lower-java-runtime.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/mmtk/magic/lower-java-runtime.cc?rev=199656&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/mmtk/magic/lower-java-runtime.cc (added)
+++ vmkit/branches/mcjit/lib/mmtk/magic/lower-java-runtime.cc Mon Jan 20 07:35:01 2014
@@ -0,0 +1,155 @@
+//===-- LowerJavaRT.cpp - Remove references to RT classes and functions  --===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Illinois Open Source 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if 0
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+  class LowerJavaRT : public ModulePass {
+  public:
+    static char ID;
+    LowerJavaRT() : ModulePass(ID) { }
+
+    virtual bool runOnModule(Module &M);
+  private:
+  };
+  char LowerJavaRT::ID = 0;
+  static RegisterPass<LowerJavaRT> X("LowerJavaRT",
+                                     "Remove references to RT");
+
+bool LowerJavaRT::runOnModule(Module& M) {
+  bool Changed = true;
+
+  for (Module::iterator I = M.begin(), E = M.end(); I != E;) {
+    Function& GV = *I;
+    ++I;
+    if (!strncmp(GV.getName().data(), "JnJVM_java", 10) ||
+        !strncmp(GV.getName().data(), "java", 4)) {
+      if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_charAt__I")) {
+  	    Function* F = M.getFunction("MMTkCharAt");
+        if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkCharAt", &M);
+      	
+        GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_Object_getClass__")) {
+  	    Function* F = M.getFunction("MMTkGetClass");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkGetClass", &M);
+      	GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_equals__Ljava_lang_Object_2")) {
+  	    Function* F = M.getFunction("MMTkStringEquals");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkStringEquals", &M);
+      	GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_length__")) {
+  	    Function* F = M.getFunction("MMTkStringLength");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkStringLength", &M);
+      	GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_indexOf__I")) {
+  	    Function* F = M.getFunction("MMTkStringIndexOf");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkStringIndexOf", &M);
+      	GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_substring__II")) {
+  	    Function* F = M.getFunction("MMTkStringSubstringII");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkStringSubstringII", &M);
+      	GV.replaceAllUsesWith(F);
+      } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_substring__I")) {
+  	    Function* F = M.getFunction("MMTkStringSubstringI");
+	      if (!F) 
+          F = Function::Create(GV.getFunctionType(),
+                               GlobalValue::ExternalLinkage, "MMTkStringSubstringI", &M);
+      	GV.replaceAllUsesWith(F);
+      } else {
+        GV.replaceAllUsesWith(Constant::getNullValue(GV.getType()));
+      }
+      GV.eraseFromParent();
+    }
+  }
+
+  // Remove all references to magic methods.
+  for (Module::iterator I = M.begin(), E = M.end(); I != E;) {
+    Function& GV = *I;
+    ++I;
+    if (!strncmp(GV.getName().data(), "JnJVM_org_vmmagic", 17)) {
+      GV.replaceAllUsesWith(Constant::getNullValue(GV.getType()));
+      GV.eraseFromParent();
+    }
+  }
+
+  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+       I != E;) {
+    GlobalValue& GV = *I;
+    ++I;
+    if (!strncmp(GV.getName().data(), "JnJVM_java", 10) ||
+        !strncmp(GV.getName().data(), "java", 4) ||
+        !strncmp(GV.getName().data(), "JnJVM_gnu", 9) ||
+        !strncmp(GV.getName().data(), "_3", 2) || // Arrays
+        !strncmp(GV.getName().data(), "gnu", 3)) {
+      GV.replaceAllUsesWith(Constant::getNullValue(GV.getType()));
+      GV.eraseFromParent();
+    }
+  }
+
+  // Replace finalization calls with null.
+  Function* F = M.getFunction("addFinalizationCandidate");
+  F->replaceAllUsesWith(Constant::getNullValue(F->getType()));
+  F->eraseFromParent();
+ 
+  // Replace VTgcmalloc with the allocator of MMTk objects in VMKit
+  F = M.getFunction("VTgcmalloc");
+  Function* Ma = M.getFunction("AllocateMagicArray");
+
+  Function* NewFunction = 
+    Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
+                     "MMTkMutatorAllocate", &M);
+
+  F->replaceAllUsesWith(NewFunction);
+  F->eraseFromParent();
+  
+  Ma->replaceAllUsesWith(NewFunction);
+  Ma->eraseFromParent();
+
+  // Finally, remove GC info from the methods. They must not have any
+  // gcroot.
+  for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
+    I->clearGC();
+  }
+
+  // Rename JavaObject type to avoid collisions when inlining
+  // malloc and barriers.
+  M.getTypeByName("JavaObject")->setName("MMTk.JavaObject");
+
+  return Changed;
+}
+
+}
+
+#endif

Added: vmkit/branches/mcjit/lib/mmtk/magic/lower-magic.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/mmtk/magic/lower-magic.cc?rev=199656&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/mmtk/magic/lower-magic.cc (added)
+++ vmkit/branches/mcjit/lib/mmtk/magic/lower-magic.cc Mon Jan 20 07:35:01 2014
@@ -0,0 +1,1318 @@
+//===----- LowerConstantCalls.cpp - Changes arrayLength calls  --------------===//
+//
+//                               JnJVM
+//
+// This file is distributed under the University of Illinois Open Source 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if 0
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <cstdio>
+
+#include "vmkit/GC.h"
+#include "vmkit/System.h"
+
+using namespace llvm;
+
+namespace vmmagic {
+
+  class LowerMagic : public FunctionPass {
+  public:
+    static char ID;
+    LowerMagic() : FunctionPass(ID) { }
+
+    virtual bool runOnFunction(Function &F);
+  private:
+  };
+  char LowerMagic::ID = 0;
+  static RegisterPass<LowerMagic> X("LowerMagic",
+                                    "Lower magic calls");
+  typedef SmallPtrSet<Instruction*,128> InstSet;
+
+static const char* AddressClass = "JnJVM_org_vmmagic_unboxed_Address_";
+static const char* AddressZeroMethod = 0;
+static const char* AddressIsZeroMethod;
+static const char* AddressMaxMethod;
+//static const char* AddressIsMaxMethod;
+//static const char* AddressFromIntSignExtendMethod;
+static const char* AddressFromIntZeroExtendMethod;
+//static const char* AddressFromLongMethod;
+static const char* AddressToObjectReferenceMethod;
+static const char* AddressToIntMethod;
+static const char* AddressToLongMethod;
+static const char* AddressToWordMethod;
+static const char* AddressPlusIntMethod;
+static const char* AddressPlusOffsetMethod;
+static const char* AddressPlusExtentMethod;
+static const char* AddressMinusIntMethod;
+//static const char* AddressMinusOffsetMethod;
+static const char* AddressMinusExtentMethod;
+static const char* AddressDiffMethod;
+static const char* AddressLTMethod;
+static const char* AddressLEMethod;
+static const char* AddressGTMethod;
+static const char* AddressGEMethod;
+static const char* AddressEQMethod;
+static const char* AddressNEMethod;
+//static const char* AddressPrefetchMethod;
+static const char* AddressLoadObjectReferenceMethod;
+static const char* AddressLoadObjectReferenceAtOffsetMethod;
+static const char* AddressLoadByteMethod;
+static const char* AddressLoadByteAtOffsetMethod;
+//static const char* AddressLoadCharMethod;
+//static const char* AddressLoadCharAtOffsetMethod;
+static const char* AddressLoadShortMethod;
+static const char* AddressLoadShortAtOffsetMethod;
+//static const char* AddressLoadFloatMethod;
+//static const char* AddressLoadFloatAtOffsetMethod;
+static const char* AddressLoadIntMethod;
+static const char* AddressLoadIntAtOffsetMethod;
+//static const char* AddressLoadLongMethod;
+//static const char* AddressLoadLongAtOffsetMethod;
+//static const char* AddressLoadDoubleMethod;
+//static const char* AddressLoadDoubleAtOffsetMethod;
+static const char* AddressLoadAddressMethod;
+static const char* AddressLoadAddressAtOffsetMethod;
+static const char* AddressLoadWordMethod;
+static const char* AddressLoadWordAtOffsetMethod;
+static const char* AddressStoreObjectReferenceMethod;
+static const char* AddressStoreObjectReferenceAtOffsetMethod;
+static const char* AddressStoreAddressMethod;
+static const char* AddressStoreAddressAtOffsetMethod;
+//static const char* AddressStoreFloatMethod;
+//static const char* AddressStoreFloatAtOffsetMethod;
+static const char* AddressStoreWordMethod;
+static const char* AddressStoreWordAtOffsetMethod;
+static const char* AddressStoreByteMethod;
+static const char* AddressStoreByteAtOffsetMethod;
+static const char* AddressStoreIntMethod;
+//static const char* AddressStoreIntAtOffsetMethod;
+//static const char* AddressStoreDoubleMethod;
+//static const char* AddressStoreDoubleAtOffsetMethod;
+//static const char* AddressStoreLongMethod;
+//static const char* AddressStoreLongAtOffsetMethod;
+//static const char* AddressStoreCharMethod;
+//static const char* AddressStoreCharAtOffsetMethod;
+static const char* AddressStoreShortMethod;
+static const char* AddressStoreShortAtOffsetMethod;
+static const char* AddressPrepareWordMethod;
+static const char* AddressPrepareWordAtOffsetMethod;
+//static const char* AddressPrepareObjectReferenceMethod;
+//static const char* AddressPrepareObjectReferenceAtOffsetMethod;
+//static const char* AddressPrepareAddressMethod;
+//static const char* AddressPrepareAddressAtOffsetMethod;
+//static const char* AddressPrepareIntMethod;
+//static const char* AddressPrepareIntAtOffsetMethod;
+//static const char* AddressAttemptIntMethod;
+//static const char* AddressAttemptIntAtOffsetMethod;
+static const char* AddressAttemptWordMethod;
+static const char* AddressAttemptWordAtOffsetMethod;
+static const char* AddressAttemptObjectReferenceMethod;
+static const char* AddressAttemptObjectReferenceAtOffsetMethod;
+//static const char* AddressAttemptAddressMethod;
+//static const char* AddressAttemptAddressAtOffsetMethod;
+
+static const char* ExtentClass = "JnJVM_org_vmmagic_unboxed_Extent_";
+static const char* ExtentToWordMethod = 0;
+static const char* ExtentFromIntSignExtendMethod;
+static const char* ExtentFromIntZeroExtendMethod;
+static const char* ExtentZeroMethod;
+static const char* ExtentOneMethod;
+static const char* ExtentMaxMethod;
+static const char* ExtentToIntMethod;
+static const char* ExtentToLongMethod;
+static const char* ExtentPlusIntMethod;
+static const char* ExtentPlusExtentMethod;
+static const char* ExtentMinusIntMethod;
+static const char* ExtentMinusExtentMethod;
+static const char* ExtentLTMethod;
+//static const char* ExtentLEMethod;
+static const char* ExtentGTMethod;
+//static const char* ExtentGEMethod;
+static const char* ExtentEQMethod;
+static const char* ExtentNEMethod;
+
+static const char* ObjectReferenceClass = 
+  "JnJVM_org_vmmagic_unboxed_ObjectReference_";
+static const char* ObjectReferenceFromObjectMethod = 0;
+static const char* ObjectReferenceNullReferenceMethod;
+static const char* ObjectReferenceToObjectMethod;
+static const char* ObjectReferenceToAddressMethod;
+static const char* ObjectReferenceIsNullMethod;
+
+static const char* OffsetClass = "JnJVM_org_vmmagic_unboxed_Offset_";
+static const char* OffsetFromIntSignExtendMethod = 0;
+static const char* OffsetFromIntZeroExtendMethod;
+static const char* OffsetZeroMethod;
+//static const char* OffsetMaxMethod;
+static const char* OffsetToIntMethod;
+static const char* OffsetToLongMethod;
+static const char* OffsetToWordMethod;
+static const char* OffsetPlusIntMethod;
+static const char* OffsetMinusIntMethod;
+static const char* OffsetMinusOffsetMethod;
+static const char* OffsetEQMethod;
+//static const char* OffsetNEMethod;
+static const char* OffsetSLTMethod;
+static const char* OffsetSLEMethod;
+static const char* OffsetSGTMethod;
+static const char* OffsetSGEMethod;
+static const char* OffsetIsZeroMethod;
+//static const char* OffsetIsMaxMethod;
+
+static const char* WordClass = "JnJVM_org_vmmagic_unboxed_Word_";
+static const char* WordFromIntSignExtendMethod = 0;
+static const char* WordFromIntZeroExtendMethod;
+//static const char* WordFromLongMethod;
+static const char* WordZeroMethod;
+static const char* WordOneMethod;
+static const char* WordMaxMethod;
+static const char* WordToIntMethod;
+static const char* WordToLongMethod;
+static const char* WordToAddressMethod;
+static const char* WordToOffsetMethod;
+static const char* WordToExtentMethod;
+static const char* WordPlusWordMethod;
+//static const char* WordPlusOffsetMethod;
+//static const char* WordPlusExtentMethod;
+static const char* WordMinusWordMethod;
+//static const char* WordMinusOffsetMethod;
+static const char* WordMinusExtentMethod;
+static const char* WordIsZeroMethod;
+//static const char* WordIsMaxMethod;
+static const char* WordLTMethod;
+static const char* WordLEMethod;
+static const char* WordGTMethod;
+static const char* WordGEMethod;
+static const char* WordEQMethod;
+static const char* WordNEMethod;
+static const char* WordAndMethod;
+static const char* WordOrMethod;
+static const char* WordNotMethod;
+static const char* WordXorMethod;
+static const char* WordLshMethod;
+static const char* WordRshlMethod;
+//static const char* WordRshaMethod;
+
+static const char* AddressArrayClass = "JnJVM_org_vmmagic_unboxed_AddressArray_";
+static const char* ExtentArrayClass = "JnJVM_org_vmmagic_unboxed_ExtentArray_";
+static const char* ObjectReferenceArrayClass = "JnJVM_org_vmmagic_unboxed_ObjectReferenceArray_";
+static const char* OffsetArrayClass = "JnJVM_org_vmmagic_unboxed_OffsetArray_";
+static const char* WordArrayClass = "JnJVM_org_vmmagic_unboxed_WordArray_";
+
+static const char* AddressArrayCreateMethod = "JnJVM_org_vmmagic_unboxed_AddressArray_create__I";
+static const char* ExtentArrayCreateMethod = "JnJVM_org_vmmagic_unboxed_ExtentArray_create__I";
+static const char* ObjectReferenceArrayCreateMethod = "JnJVM_org_vmmagic_unboxed_ObjectReferenceArray_create__I";
+static const char* OffsetArrayCreateMethod = "JnJVM_org_vmmagic_unboxed_OffsetArray_create__I";
+static const char* WordArrayCreateMethod = "JnJVM_org_vmmagic_unboxed_WordArray_create__I";
+
+static const char* AddressArrayGetMethod = "JnJVM_org_vmmagic_unboxed_AddressArray_get__I";
+static const char* ExtentArrayGetMethod = "JnJVM_org_vmmagic_unboxed_ExtentArray_get__I";
+static const char* ObjectReferenceArrayGetMethod = "JnJVM_org_vmmagic_unboxed_ObjectReferenceArray_get__I";
+static const char* OffsetArrayGetMethod = "JnJVM_org_vmmagic_unboxed_OffsetArray_get__I";
+static const char* WordArrayGetMethod = "JnJVM_org_vmmagic_unboxed_WordArray_get__I";
+
+static const char* AddressArraySetMethod = "JnJVM_org_vmmagic_unboxed_AddressArray_set__ILorg_vmmagic_unboxed_Address_2";
+static const char* ExtentArraySetMethod = "JnJVM_org_vmmagic_unboxed_ExtentArray_set__ILorg_vmmagic_unboxed_Extent_2";
+static const char* ObjectReferenceArraySetMethod = "JnJVM_org_vmmagic_unboxed_ObjectReferenceArray_set__ILorg_vmmagic_unboxed_ObjectReference_2";
+static const char* OffsetArraySetMethod = "JnJVM_org_vmmagic_unboxed_OffsetArray_set__ILorg_vmmagic_unboxed_Offset_2";
+static const char* WordArraySetMethod = "JnJVM_org_vmmagic_unboxed_WordArray_set__ILorg_vmmagic_unboxed_Word_2";
+
+static const char* AddressArrayLengthMethod = "JnJVM_org_vmmagic_unboxed_AddressArray_lenght__";
+static const char* ExtentArrayLengthMethod = "JnJVM_org_vmmagic_unboxed_ExtentArray_length__";
+static const char* ObjectReferenceArrayLengthMethod = "JnJVM_org_vmmagic_unboxed_ObjectReferenceArray_length__";
+static const char* OffsetArrayLengthMethod = "JnJVM_org_vmmagic_unboxed_OffsetArray_length__";
+static const char* WordArrayLengthMethod = "JnJVM_org_vmmagic_unboxed_WordArray_length__";
+
+
+
+static void initialiseFunctions(Module* M) {
+  if (!AddressZeroMethod) {
+    AddressZeroMethod = "JnJVM_org_vmmagic_unboxed_Address_zero__";
+    AddressMaxMethod = "JnJVM_org_vmmagic_unboxed_Address_max__";
+    AddressStoreObjectReferenceMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_ObjectReference_2";
+    AddressStoreObjectReferenceAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Offset_2";
+    AddressLoadObjectReferenceMethod = "JnJVM_org_vmmagic_unboxed_Address_loadObjectReference__";
+    AddressLoadAddressMethod = "JnJVM_org_vmmagic_unboxed_Address_loadAddress__";
+    AddressLoadWordMethod = "JnJVM_org_vmmagic_unboxed_Address_loadWord__";
+    AddressDiffMethod = "JnJVM_org_vmmagic_unboxed_Address_diff__Lorg_vmmagic_unboxed_Address_2";
+    AddressPlusOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_plus__Lorg_vmmagic_unboxed_Offset_2";
+    AddressStoreAddressMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_Address_2";
+    AddressPlusIntMethod = "JnJVM_org_vmmagic_unboxed_Address_plus__I";
+    AddressLTMethod = "JnJVM_org_vmmagic_unboxed_Address_LT__Lorg_vmmagic_unboxed_Address_2";
+    AddressGEMethod = "JnJVM_org_vmmagic_unboxed_Address_GE__Lorg_vmmagic_unboxed_Address_2";
+    AddressStoreWordMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_Word_2";
+    AddressToObjectReferenceMethod = "JnJVM_org_vmmagic_unboxed_Address_toObjectReference__";
+    AddressToWordMethod = "JnJVM_org_vmmagic_unboxed_Address_toWord__";
+    AddressPrepareWordMethod = "JnJVM_org_vmmagic_unboxed_Address_prepareWord__";
+    AddressAttemptWordAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_attempt__Lorg_vmmagic_unboxed_Word_2Lorg_vmmagic_unboxed_Word_2Lorg_vmmagic_unboxed_Offset_2";
+    AddressAttemptObjectReferenceAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_attempt__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Offset_2";
+    AddressPrepareWordAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_prepareWord__Lorg_vmmagic_unboxed_Offset_2";
+    AddressLoadWordAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadWord__Lorg_vmmagic_unboxed_Offset_2";
+    AddressStoreWordAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_Word_2Lorg_vmmagic_unboxed_Offset_2";
+    AddressPlusExtentMethod = "JnJVM_org_vmmagic_unboxed_Address_plus__Lorg_vmmagic_unboxed_Extent_2";
+    AddressIsZeroMethod = "JnJVM_org_vmmagic_unboxed_Address_isZero__";
+    AddressStoreAddressAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_store__Lorg_vmmagic_unboxed_Address_2Lorg_vmmagic_unboxed_Offset_2";
+    AddressGTMethod = "JnJVM_org_vmmagic_unboxed_Address_GT__Lorg_vmmagic_unboxed_Address_2";
+    AddressLoadAddressAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadAddress__Lorg_vmmagic_unboxed_Offset_2";
+    AddressEQMethod = "JnJVM_org_vmmagic_unboxed_Address_EQ__Lorg_vmmagic_unboxed_Address_2";
+    AddressLoadObjectReferenceAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadObjectReference__Lorg_vmmagic_unboxed_Offset_2";
+    AddressLEMethod = "JnJVM_org_vmmagic_unboxed_Address_LE__Lorg_vmmagic_unboxed_Address_2";
+    AddressAttemptWordMethod = "JnJVM_org_vmmagic_unboxed_Address_attempt__Lorg_vmmagic_unboxed_Word_2Lorg_vmmagic_unboxed_Word_2";
+    AddressAttemptObjectReferenceMethod = "JnJVM_org_vmmagic_unboxed_Address_attempt__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2";
+    AddressNEMethod = "JnJVM_org_vmmagic_unboxed_Address_NE__Lorg_vmmagic_unboxed_Address_2";
+    AddressToLongMethod = "JnJVM_org_vmmagic_unboxed_Address_toLong__";
+    AddressMinusExtentMethod = "JnJVM_org_vmmagic_unboxed_Address_minus__Lorg_vmmagic_unboxed_Extent_2";
+    AddressLoadShortAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadShort__Lorg_vmmagic_unboxed_Offset_2";
+    AddressStoreShortAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_store__SLorg_vmmagic_unboxed_Offset_2";
+    AddressLoadShortMethod = "JnJVM_org_vmmagic_unboxed_Address_loadShort__";
+    AddressStoreShortMethod = "JnJVM_org_vmmagic_unboxed_Address_store__S";
+    AddressLoadByteMethod = "JnJVM_org_vmmagic_unboxed_Address_loadByte__";
+    AddressLoadIntMethod = "JnJVM_org_vmmagic_unboxed_Address_loadInt__";
+    AddressStoreIntMethod = "JnJVM_org_vmmagic_unboxed_Address_store__I";
+    AddressStoreByteMethod = "JnJVM_org_vmmagic_unboxed_Address_store__B";
+    AddressLoadByteAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadByte__Lorg_vmmagic_unboxed_Offset_2";
+    AddressMinusIntMethod = "JnJVM_org_vmmagic_unboxed_Address_minus__I";
+    AddressLoadIntAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_loadInt__Lorg_vmmagic_unboxed_Offset_2";
+    AddressStoreByteAtOffsetMethod = "JnJVM_org_vmmagic_unboxed_Address_store__BLorg_vmmagic_unboxed_Offset_2";
+    AddressFromIntZeroExtendMethod = "JnJVM_org_vmmagic_unboxed_Address_fromIntZeroExtend__I";
+    AddressToIntMethod = "JnJVM_org_vmmagic_unboxed_Address_toInt__";
+    
+    ExtentToWordMethod = "JnJVM_org_vmmagic_unboxed_Extent_toWord__";
+    ExtentMinusExtentMethod = "JnJVM_org_vmmagic_unboxed_Extent_minus__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentPlusExtentMethod = "JnJVM_org_vmmagic_unboxed_Extent_plus__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentPlusIntMethod = "JnJVM_org_vmmagic_unboxed_Extent_plus__I";
+    ExtentMinusIntMethod = "JnJVM_org_vmmagic_unboxed_Extent_minus__I";
+    ExtentFromIntZeroExtendMethod = "JnJVM_org_vmmagic_unboxed_Extent_fromIntZeroExtend__I";
+    ExtentFromIntSignExtendMethod = "JnJVM_org_vmmagic_unboxed_Extent_fromIntSignExtend__I";
+    ExtentOneMethod = "JnJVM_org_vmmagic_unboxed_Extent_one__";
+    ExtentNEMethod = "JnJVM_org_vmmagic_unboxed_Extent_NE__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentZeroMethod = "JnJVM_org_vmmagic_unboxed_Extent_zero__";
+    ExtentToLongMethod = "JnJVM_org_vmmagic_unboxed_Extent_toLong__";
+    ExtentToIntMethod = "JnJVM_org_vmmagic_unboxed_Extent_toInt__";
+    ExtentEQMethod = "JnJVM_org_vmmagic_unboxed_Extent_EQ__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentGTMethod = "JnJVM_org_vmmagic_unboxed_Extent_GT__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentLTMethod = "JnJVM_org_vmmagic_unboxed_Extent_LT__Lorg_vmmagic_unboxed_Extent_2";
+    ExtentMaxMethod = "JnJVM_org_vmmagic_unboxed_Extent_max__";
+
+    ObjectReferenceFromObjectMethod = "JnJVM_org_vmmagic_unboxed_ObjectReference_fromObject__Ljava_lang_Object_2";
+    ObjectReferenceToObjectMethod = "JnJVM_org_vmmagic_unboxed_ObjectReference_toObject__";
+    ObjectReferenceNullReferenceMethod = "JnJVM_org_vmmagic_unboxed_ObjectReference_nullReference__";
+    ObjectReferenceToAddressMethod = "JnJVM_org_vmmagic_unboxed_ObjectReference_toAddress__";
+    ObjectReferenceIsNullMethod = "JnJVM_org_vmmagic_unboxed_ObjectReference_isNull__";
+
+    WordOrMethod = "JnJVM_org_vmmagic_unboxed_Word_or__Lorg_vmmagic_unboxed_Word_2";
+    WordRshlMethod = "JnJVM_org_vmmagic_unboxed_Word_rshl__I";
+    WordToIntMethod = "JnJVM_org_vmmagic_unboxed_Word_toInt__";
+    WordNotMethod = "JnJVM_org_vmmagic_unboxed_Word_not__";
+    WordZeroMethod = "JnJVM_org_vmmagic_unboxed_Word_zero__";
+    WordOneMethod = "JnJVM_org_vmmagic_unboxed_Word_one__";
+    WordAndMethod = "JnJVM_org_vmmagic_unboxed_Word_and__Lorg_vmmagic_unboxed_Word_2";
+    WordToAddressMethod = "JnJVM_org_vmmagic_unboxed_Word_toAddress__";
+    WordLshMethod = "JnJVM_org_vmmagic_unboxed_Word_lsh__I";
+    WordMinusWordMethod = "JnJVM_org_vmmagic_unboxed_Word_minus__Lorg_vmmagic_unboxed_Word_2";
+    WordLTMethod = "JnJVM_org_vmmagic_unboxed_Word_LT__Lorg_vmmagic_unboxed_Word_2";
+    WordPlusWordMethod = "JnJVM_org_vmmagic_unboxed_Word_plus__Lorg_vmmagic_unboxed_Word_2";
+    WordLEMethod = "JnJVM_org_vmmagic_unboxed_Word_LE__Lorg_vmmagic_unboxed_Word_2";
+    WordGEMethod = "JnJVM_org_vmmagic_unboxed_Word_GE__Lorg_vmmagic_unboxed_Word_2";
+    WordEQMethod = "JnJVM_org_vmmagic_unboxed_Word_EQ__Lorg_vmmagic_unboxed_Word_2";
+    WordNEMethod = "JnJVM_org_vmmagic_unboxed_Word_NE__Lorg_vmmagic_unboxed_Word_2";
+    WordFromIntSignExtendMethod = "JnJVM_org_vmmagic_unboxed_Word_fromIntSignExtend__I";
+    WordIsZeroMethod = "JnJVM_org_vmmagic_unboxed_Word_isZero__";
+    WordXorMethod = "JnJVM_org_vmmagic_unboxed_Word_xor__Lorg_vmmagic_unboxed_Word_2";
+    WordFromIntZeroExtendMethod = "JnJVM_org_vmmagic_unboxed_Word_fromIntZeroExtend__I";
+    WordToExtentMethod = "JnJVM_org_vmmagic_unboxed_Word_toExtent__";
+    WordMinusExtentMethod = "JnJVM_org_vmmagic_unboxed_Word_minus__Lorg_vmmagic_unboxed_Extent_2";
+    WordToLongMethod = "JnJVM_org_vmmagic_unboxed_Word_toLong__";
+    WordMaxMethod = "JnJVM_org_vmmagic_unboxed_Word_max__";
+    WordToOffsetMethod = "JnJVM_org_vmmagic_unboxed_Word_toOffset__";
+    WordGTMethod = "JnJVM_org_vmmagic_unboxed_Word_GT__Lorg_vmmagic_unboxed_Word_2";
+
+
+    OffsetSLTMethod = "JnJVM_org_vmmagic_unboxed_Offset_sLT__Lorg_vmmagic_unboxed_Offset_2";
+    OffsetFromIntSignExtendMethod = "JnJVM_org_vmmagic_unboxed_Offset_fromIntSignExtend__I";
+    OffsetSGTMethod = "JnJVM_org_vmmagic_unboxed_Offset_sGT__Lorg_vmmagic_unboxed_Offset_2";
+    OffsetPlusIntMethod = "JnJVM_org_vmmagic_unboxed_Offset_plus__I";
+    OffsetZeroMethod = "JnJVM_org_vmmagic_unboxed_Offset_zero__";
+    OffsetToWordMethod = "JnJVM_org_vmmagic_unboxed_Offset_toWord__";
+    OffsetFromIntZeroExtendMethod = "JnJVM_org_vmmagic_unboxed_Offset_fromIntZeroExtend__I";
+    OffsetSGEMethod = "JnJVM_org_vmmagic_unboxed_Offset_sGE__Lorg_vmmagic_unboxed_Offset_2";
+    OffsetToIntMethod = "JnJVM_org_vmmagic_unboxed_Offset_toInt__";
+    OffsetToLongMethod = "JnJVM_org_vmmagic_unboxed_Offset_toLong__";
+    OffsetIsZeroMethod = "JnJVM_org_vmmagic_unboxed_Offset_isZero__";
+    OffsetMinusIntMethod = "JnJVM_org_vmmagic_unboxed_Offset_minus__I";
+    OffsetSLEMethod = "JnJVM_org_vmmagic_unboxed_Offset_sLE__Lorg_vmmagic_unboxed_Offset_2";
+    OffsetEQMethod = "JnJVM_org_vmmagic_unboxed_Offset_EQ__Lorg_vmmagic_unboxed_Offset_2";
+    OffsetMinusOffsetMethod = "JnJVM_org_vmmagic_unboxed_Offset_minus__Lorg_vmmagic_unboxed_Offset_2";
+  }
+}
+
+static bool removePotentialNullCheck(BasicBlock* Cur, Value* Obj, InstSet& RemoveSet) {
+  if (!Obj->getType()->isPointerTy()) return false;
+
+  if (vmkit::System::SupportsHardwareNullCheck()) {
+    bool changed = false;
+    for (Value::use_iterator I = Obj->use_begin(), E = Obj->use_end(); I != E; I++) {
+      if (GetElementPtrInst* GE = dyn_cast<GetElementPtrInst>(*I)) {
+        for (Value::use_iterator II = GE->use_begin(), EE = GE->use_end(); II != EE; II++) {
+          if (LoadInst* LI = dyn_cast<LoadInst>(*II)) {
+            if (LI->isVolatile()) {
+              assert(LI->use_empty());
+              RemoveSet.insert(LI);
+              changed = true;
+            }
+          }
+        }
+      }
+    }
+    return changed;
+  } else {
+    BasicBlock* BB = Cur->getUniquePredecessor();
+    LLVMContext& Context = Cur->getParent()->getContext();
+    if (BB) {
+      Instruction* T = BB->getTerminator();
+      if (dyn_cast<BranchInst>(T) && T != BB->begin()) {
+        BasicBlock::iterator BIE = BB->end();
+        --BIE; // Terminator
+        --BIE; // Null test
+        if (ICmpInst* IE = dyn_cast<ICmpInst>(BIE)) {
+          if (IE->getPredicate() == ICmpInst::ICMP_EQ &&
+              IE->getOperand(0) == Obj &&
+              IE->getOperand(1) == Constant::getNullValue(Obj->getType())) {
+            BIE->replaceAllUsesWith(ConstantInt::getFalse(Context));
+            BIE->eraseFromParent();
+            return true;
+          }
+        }
+      }
+    }
+  }
+  return false;
+}
+
+bool LowerMagic::runOnFunction(Function& F) {
+  Module* globalModule = F.getParent();
+  LLVMContext& Context = globalModule->getContext();
+  bool Changed = false;
+  llvm::Type* pointerSizeType = 
+    globalModule->getPointerSize() == llvm::Module::Pointer32 ?
+      Type::getInt32Ty(Context) : Type::getInt64Ty(Context);
+ 
+   Constant* constantPtrLogSize = 
+    ConstantInt::get(Type::getInt32Ty(Context), sizeof(void*) == 8 ? 3 : 2);
+
+  llvm::Type* ptrType = PointerType::getUnqual(Type::getInt8Ty(Context));
+  llvm::Type* ptrSizeType = PointerType::getUnqual(pointerSizeType);
+
+
+  initialiseFunctions(globalModule);
+
+  Function* MMalloc = globalModule->getFunction("AllocateMagicArray");
+  if (!MMalloc) {
+    std::vector<Type*>FuncTyArgs;
+    FuncTyArgs.push_back(Type::getInt32Ty(Context));
+    FuncTyArgs.push_back(ptrType);
+    FunctionType* FuncTy = FunctionType::get(ptrType, FuncTyArgs, false);
+
+
+    MMalloc = Function::Create(FuncTy, GlobalValue::ExternalLinkage, "AllocateMagicArray",
+                               globalModule);
+  }
+
+
+  InstSet RemoveSet;
+
+  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; BI++) { 
+    BasicBlock *Cur = BI; 
+    for (BasicBlock::iterator II = Cur->begin(), IE = Cur->end(); II != IE;) {
+      Instruction *I = II;
+      II++;
+      if (I->getOpcode() != Instruction::Call &&
+          I->getOpcode() != Instruction::Invoke) {
+        continue;
+      }
+
+      CallSite Call(I);
+      Instruction* CI = I;
+        Value* V = Call.getCalledValue();
+        if (Function* FCur = dyn_cast<Function>(V)) {
+          const char* name = FCur->getName().data();
+          unsigned len = FCur->getName().size();
+          if (len > strlen(AddressClass) && 
+              !memcmp(AddressClass, name, strlen(AddressClass))) {
+            
+            Changed = true;
+            // Remove the null check
+            if (Call.arg_begin() != Call.arg_end()) {
+              removePotentialNullCheck(Cur, Call.getArgument(0), RemoveSet);
+            }
+
+            if (!strcmp(FCur->getName().data(), AddressZeroMethod)) {
+              Constant* N = Constant::getNullValue(FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressMaxMethod)) {
+              ConstantInt* M = ConstantInt::get(Type::getInt64Ty(Context), (uint64_t)-1);
+              Constant* N = ConstantExpr::getIntToPtr(M, FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressStoreObjectReferenceMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreAddressMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreShortMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreByteMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreIntMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreWordMethod)) {
+              Value* Addr = Call.getArgument(0);
+              Value* Obj = Call.getArgument(1);
+              Type* Ty = PointerType::getUnqual(Obj->getType());
+              Addr = new BitCastInst(Addr, Ty, "", CI);
+              new StoreInst(Obj, Addr, CI);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressLoadObjectReferenceMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadAddressMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadWordMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadShortMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadByteMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadIntMethod) ||
+                       !strcmp(FCur->getName().data(), AddressPrepareWordMethod)) {
+              Value* Addr = Call.getArgument(0);
+              Type* Ty = PointerType::getUnqual(FCur->getReturnType());
+              Addr = new BitCastInst(Addr, Ty, "", CI);
+              Value* LD = new LoadInst(Addr, "", CI);
+              CI->replaceAllUsesWith(LD);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressDiffMethod) ||
+                       !strcmp(FCur->getName().data(), AddressMinusExtentMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressPlusOffsetMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressPlusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressMinusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressLTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+            	Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+            	Val1 = BinaryOperator::CreateAdd(Val1, M, "", CI);
+            	Val2 = BinaryOperator::CreateAdd(Val2, M, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_ULT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressGTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+            	Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+            	Val1 = BinaryOperator::CreateAdd(Val1, M, "", CI);
+            	Val2 = BinaryOperator::CreateAdd(Val2, M, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_UGT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressEQMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressNEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_NE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressLEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+            	Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+            	Val1 = BinaryOperator::CreateAdd(Val1, M, "", CI);
+            	Val2 = BinaryOperator::CreateAdd(Val2, M, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_ULE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressGEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+            	Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+            	Val1 = BinaryOperator::CreateAdd(Val1, M, "", CI);
+            	Val2 = BinaryOperator::CreateAdd(Val2, M, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_UGE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressToObjectReferenceMethod)){
+            	Value* Val = Call.getArgument(0);
+            	Val = new PtrToIntInst(Val, pointerSizeType, "", CI);
+            	Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+            	Val = BinaryOperator::CreateAdd(Val, M, "", CI);
+            	Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+            	CI->replaceAllUsesWith(Val);
+            	CI->eraseFromParent();
+            } else if(!strcmp(FCur->getName().data(), AddressToWordMethod)) {
+            	Value* Val = Call.getArgument(0);
+            	Val = new BitCastInst(Val, FCur->getReturnType(), "", CI);
+            	CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressAttemptWordAtOffsetMethod) ||
+            		        !strcmp(FCur->getName().data(), AddressAttemptObjectReferenceAtOffsetMethod)) {
+              Value* Ptr = Call.getArgument(0);
+              Value* Old = Call.getArgument(1);
+              Value* Val = Call.getArgument(2);
+              Value* Offset = Call.getArgument(3);
+
+              Ptr = new PtrToIntInst(Ptr, pointerSizeType, "", CI);
+              Offset = new PtrToIntInst(Offset, pointerSizeType, "", CI);
+              Ptr = BinaryOperator::CreateAdd(Ptr, Offset, "", CI);
+              Type* Ty = PointerType::getUnqual(pointerSizeType);
+              Ptr = new IntToPtrInst(Ptr, Ty, "", CI);
+              Old = new PtrToIntInst(Old, pointerSizeType, "", CI);
+              Val = new PtrToIntInst(Val, pointerSizeType, "", CI);
+              
+              Value* res = new AtomicCmpXchgInst(
+                  Ptr, Old, Val, SequentiallyConsistent, CrossThread, CI);
+              res = new ICmpInst(CI, ICmpInst::ICMP_EQ, res, Old, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressAttemptWordMethod) ||
+            		        !strcmp(FCur->getName().data(), AddressAttemptObjectReferenceMethod)) {
+              Value* Ptr = Call.getArgument(0);
+              Value* Old = Call.getArgument(1);
+              Value* Val = Call.getArgument(2);
+
+              Type* Ty = PointerType::getUnqual(pointerSizeType);
+              Ptr = new BitCastInst(Ptr, Ty, "", CI);
+              Old = new PtrToIntInst(Old, pointerSizeType, "", CI);
+              Val = new PtrToIntInst(Val, pointerSizeType, "", CI);
+              
+              Value* res = new AtomicCmpXchgInst(
+                  Ptr, Old, Val, SequentiallyConsistent, CrossThread, CI);
+              res = new ICmpInst(CI, ICmpInst::ICMP_EQ, res, Old, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressPrepareWordAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadWordAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadAddressAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadObjectReferenceAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadByteAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadIntAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressLoadShortAtOffsetMethod)) {
+              Value* Ptr = Call.getArgument(0);
+              Value* Offset = Call.getArgument(1);
+
+              Ptr = new PtrToIntInst(Ptr, pointerSizeType, "", CI);
+              Offset = new PtrToIntInst(Offset, pointerSizeType, "", CI);
+              Ptr = BinaryOperator::CreateAdd(Ptr, Offset, "", CI);
+              Type* Ty = PointerType::getUnqual(FCur->getReturnType());
+              Ptr = new IntToPtrInst(Ptr, Ty, "", CI);
+              Value* res = new LoadInst(Ptr, "", CI);
+
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressStoreWordAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreAddressAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreByteAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreShortAtOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), AddressStoreObjectReferenceAtOffsetMethod)) {
+              Value* Ptr = Call.getArgument(0);
+              Value* Val = Call.getArgument(1);
+              Value* Offset = Call.getArgument(2);
+
+              Ptr = new PtrToIntInst(Ptr, pointerSizeType, "", CI);
+              Offset = new PtrToIntInst(Offset, pointerSizeType, "", CI);
+              Ptr = BinaryOperator::CreateAdd(Ptr, Offset, "", CI);
+              Type* Ty = PointerType::getUnqual(Val->getType());
+              Ptr = new IntToPtrInst(Ptr, Ty, "", CI);
+              new StoreInst(Val, Ptr, CI);
+
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressPlusExtentMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressIsZeroMethod)) {
+              Value* Val = Call.getArgument(0);
+              Constant* N = Constant::getNullValue(Val->getType());
+              Value* Res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val, N, "");
+              Res = new ZExtInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressToLongMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt64Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressFromIntZeroExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new ZExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), AddressToIntMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt32Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else {
+              fprintf(stderr, "Implement me %s\n", name);
+              abort();
+            }
+
+          } else if (len > strlen(ExtentClass) && 
+              !memcmp(ExtentClass, name, strlen(ExtentClass))) {
+            
+            Changed = true;
+            // Remove the null check
+            if (Call.arg_begin() != Call.arg_end()) {
+              removePotentialNullCheck(Cur, Call.getArgument(0), RemoveSet);
+            }
+
+            if (!strcmp(FCur->getName().data(), ExtentToWordMethod)) {
+              CI->replaceAllUsesWith(Call.getArgument(0));
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentMinusExtentMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentPlusExtentMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentPlusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentMinusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentFromIntZeroExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new ZExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentFromIntSignExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new SExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentOneMethod)) {
+              Constant* N = ConstantInt::get(pointerSizeType, 1);
+              N = ConstantExpr::getIntToPtr(N, FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentNEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_NE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentEQMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentGTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_UGT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentLTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_ULT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentZeroMethod)) {
+              Constant* N = Constant::getNullValue(FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentToLongMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt64Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentToIntMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt32Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ExtentMaxMethod)) {
+              ConstantInt* M = ConstantInt::get(Type::getInt64Ty(Context), (uint64_t)-1);
+              Constant* N = ConstantExpr::getIntToPtr(M, FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else {
+              fprintf(stderr, "Implement me %s\n", name);
+              abort();
+            }
+          } else if (len > strlen(OffsetClass) && 
+              !memcmp(OffsetClass, name, strlen(OffsetClass))) {
+            
+            Changed = true;
+            // Remove the null check
+            if (Call.arg_begin() != Call.arg_end()) {
+              removePotentialNullCheck(Cur, Call.getArgument(0), RemoveSet);
+            }
+            
+            if (!strcmp(FCur->getName().data(), OffsetSLTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_SLT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetToWordMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new BitCastInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetZeroMethod)) {
+              Constant* N = Constant::getNullValue(FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetSGTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_SGT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetSGEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_SGE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetSLEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_SLE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetEQMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetFromIntSignExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new SExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetFromIntZeroExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new ZExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetPlusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetToIntMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt32Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetToLongMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt64Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetIsZeroMethod)) {
+              Value* Val = Call.getArgument(0);
+              Constant* N = Constant::getNullValue(Val->getType());
+              Value* Res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val, N, "");
+              Res = new ZExtInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetMinusIntMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), OffsetMinusOffsetMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else {
+              fprintf(stderr, "Implement me %s\n", name);
+              abort();
+            }
+          } else if (len > strlen(ObjectReferenceClass) && 
+            !memcmp(ObjectReferenceClass, name, strlen(ObjectReferenceClass))) {
+           
+            Changed = true;
+            // Remove the null check
+            if (Call.arg_begin() != Call.arg_end()) {
+              removePotentialNullCheck(Cur, Call.getArgument(0), RemoveSet);
+            }
+
+            if (!strcmp(FCur->getName().data(), ObjectReferenceNullReferenceMethod)) {
+              Constant* N = Constant::getNullValue(FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ObjectReferenceFromObjectMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new BitCastInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ObjectReferenceToAddressMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, pointerSizeType, "", CI);
+              Constant* M = ConstantInt::get(pointerSizeType, gcHeader::hiddenHeaderSize());
+              Val = BinaryOperator::CreateSub(Val, M, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ObjectReferenceToObjectMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new BitCastInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), ObjectReferenceIsNullMethod)) {
+              Value* Val = Call.getArgument(0);
+              Constant* N = Constant::getNullValue(Val->getType());
+              Value* Res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val, N, "");
+              Res = new ZExtInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else {
+              fprintf(stderr, "Implement me %s\n", name);
+              abort();
+            }
+          } else if (len > strlen(WordClass) && 
+              !memcmp(WordClass, name, strlen(WordClass))) {
+           
+            Changed = true;
+            // Remove the null check
+            if (Call.arg_begin() != Call.arg_end()) {
+              removePotentialNullCheck(Cur, Call.getArgument(0), RemoveSet);
+            }
+             
+            if (!strcmp(FCur->getName().data(), WordOrMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* Res = BinaryOperator::CreateOr(Val1, Val2, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordAndMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* Res = BinaryOperator::CreateAnd(Val1, Val2, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordXorMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* Res = BinaryOperator::CreateXor(Val1, Val2, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordRshlMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* Res = BinaryOperator::CreateLShr(Val1, Val2, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordLshMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              if (Val2->getType() != pointerSizeType)
+                Val2 = new ZExtInst(Val2, pointerSizeType, "", CI);
+              Value* Res = BinaryOperator::CreateShl(Val1, Val2, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordToIntMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt32Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordNotMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, pointerSizeType, "", CI);
+              Constant* M1 = ConstantInt::get(pointerSizeType, -1);
+              Value* Res = BinaryOperator::CreateXor(Val, M1, "", CI);
+              Res = new IntToPtrInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordZeroMethod)) {
+              Constant* N = Constant::getNullValue(FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordOneMethod)) {
+              Constant* N = ConstantInt::get(pointerSizeType, 1);
+              N = ConstantExpr::getIntToPtr(N, FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordToAddressMethod) ||
+                       !strcmp(FCur->getName().data(), WordToOffsetMethod) ||
+                       !strcmp(FCur->getName().data(), WordToExtentMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new BitCastInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordMinusWordMethod) ||
+                       !strcmp(FCur->getName().data(), WordMinusExtentMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateSub(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordPlusWordMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = BinaryOperator::CreateAdd(Val1, Val2, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordLTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_ULT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordLEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_ULE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordGEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_UGE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordEQMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordGTMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_UGT, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordNEMethod)) {
+              Value* Val1 = Call.getArgument(0);
+              Value* Val2 = Call.getArgument(1);
+              Val1 = new PtrToIntInst(Val1, pointerSizeType, "", CI);
+              Val2 = new PtrToIntInst(Val2, pointerSizeType, "", CI);
+              Value* res = new ICmpInst(CI, ICmpInst::ICMP_NE, Val1, Val2, "");
+              res = new ZExtInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordFromIntSignExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new SExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordFromIntZeroExtendMethod)) {
+              Value* Val = Call.getArgument(0);
+              if (pointerSizeType != Type::getInt32Ty(Context))
+                Val = new ZExtInst(Val, pointerSizeType, "", CI);
+              Val = new IntToPtrInst(Val, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordIsZeroMethod)) {
+              Value* Val = Call.getArgument(0);
+              Constant* N = Constant::getNullValue(Val->getType());
+              Value* Res = new ICmpInst(CI, ICmpInst::ICMP_EQ, Val, N, "");
+              Res = new ZExtInst(Res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(Res);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordToLongMethod)) {
+              Value* Val = Call.getArgument(0);
+              Val = new PtrToIntInst(Val, Type::getInt64Ty(Context), "", CI);
+              CI->replaceAllUsesWith(Val);
+              CI->eraseFromParent();
+            } else if (!strcmp(FCur->getName().data(), WordMaxMethod)) {
+              ConstantInt* M = ConstantInt::get(Type::getInt64Ty(Context), (uint64_t)-1);
+              Constant* N = ConstantExpr::getIntToPtr(M, FCur->getReturnType());
+              CI->replaceAllUsesWith(N);
+              CI->eraseFromParent();
+            } else {
+              fprintf(stderr, "Implement me %s\n", name);
+              abort();
+            }
+          } else if (
+              (len > strlen(AddressArrayClass) && 
+               !memcmp(AddressArrayClass, name, strlen(AddressArrayClass))) ||
+              (len > strlen(OffsetArrayClass) && 
+               !memcmp(OffsetArrayClass, name, strlen(OffsetArrayClass))) ||
+              (len > strlen(WordArrayClass) && 
+               !memcmp(WordArrayClass, name, strlen(WordArrayClass))) ||
+              (len > strlen(ObjectReferenceArrayClass) && 
+               !memcmp(ObjectReferenceArrayClass, name, strlen(ObjectReferenceArrayClass))) ||
+              (len > strlen(ExtentArrayClass) && 
+               !memcmp(ExtentArrayClass, name, strlen(ExtentArrayClass)))) {
+            Changed = true;
+            
+            if (!strcmp(FCur->getName().data(), AddressArrayCreateMethod) ||
+                !strcmp(FCur->getName().data(), OffsetArrayCreateMethod) ||
+                !strcmp(FCur->getName().data(), WordArrayCreateMethod) ||
+                !strcmp(FCur->getName().data(), ExtentArrayCreateMethod) ||
+                !strcmp(FCur->getName().data(), ObjectReferenceArrayCreateMethod)) {
+              Value* Val = Call.getArgument(0);
+              ConstantInt* One = ConstantInt::get(Type::getInt32Ty(Context), (uint64_t)1);
+              Value* Length = BinaryOperator::CreateAdd(Val, One, "", CI);
+              Length = BinaryOperator::CreateShl(Length, constantPtrLogSize, "", CI);
+              Val = new IntToPtrInst(Val, ptrType, "", CI);
+              Value* args[2] = { Length, Val };
+              Value* res = CallInst::Create(MMalloc, args, "", CI);
+              res = new BitCastInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent();
+
+            } else if (!strcmp(FCur->getName().data(), AddressArrayGetMethod) ||
+                !strcmp(FCur->getName().data(), OffsetArrayGetMethod) ||
+                !strcmp(FCur->getName().data(), WordArrayGetMethod) ||
+                !strcmp(FCur->getName().data(), ExtentArrayGetMethod) ||
+                !strcmp(FCur->getName().data(), ObjectReferenceArrayGetMethod)) {
+              
+              Value* Array = Call.getArgument(0);
+              Value* Index = Call.getArgument(1);
+              ConstantInt* One = ConstantInt::get(Type::getInt32Ty(Context), (uint64_t)1);
+              Index = BinaryOperator::CreateAdd(Index, One, "", CI);
+              Array = new BitCastInst(Array, ptrSizeType, "", CI);
+              Value* res = GetElementPtrInst::Create(Array, Index, "", CI);
+              res = new LoadInst(res, "", CI);
+              res = new IntToPtrInst(res, FCur->getReturnType(), "", CI);
+              CI->replaceAllUsesWith(res);
+              CI->eraseFromParent(); 
+            
+            } else if (!strcmp(FCur->getName().data(), AddressArraySetMethod) ||
+                !strcmp(FCur->getName().data(), OffsetArraySetMethod) ||
+                !strcmp(FCur->getName().data(), WordArraySetMethod) ||
+                !strcmp(FCur->getName().data(), ExtentArraySetMethod) ||
+                !strcmp(FCur->getName().data(), ObjectReferenceArraySetMethod)) {
+              
+              Value* Array = Call.getArgument(0);
+              Value* Index = Call.getArgument(1);
+              Value* Element = Call.getArgument(2);
+              ConstantInt* One = ConstantInt::get(Type::getInt32Ty(Context), (uint64_t)1);
+              
+              Index = BinaryOperator::CreateAdd(Index, One, "", CI);
+              Array = new BitCastInst(Array, ptrSizeType, "", CI);
+              Value* ptr = GetElementPtrInst::Create(Array, Index, "", CI);
+              Element = new PtrToIntInst(Element, pointerSizeType, "", CI);
+              new StoreInst(Element, ptr, CI);
+              CI->eraseFromParent(); 
+            
+            } else if (!strcmp(FCur->getName().data(), AddressArrayLengthMethod) ||
+                !strcmp(FCur->getName().data(), OffsetArrayLengthMethod) ||
+                !strcmp(FCur->getName().data(), WordArrayLengthMethod) ||
+                !strcmp(FCur->getName().data(), ExtentArrayLengthMethod) ||
+                !strcmp(FCur->getName().data(), ObjectReferenceArrayLengthMethod)) {
+              
+              Value* Array = Call.getArgument(0);
+              Array = new BitCastInst(Array, ptrSizeType, "", CI);
+              Value* Length = new LoadInst(Array, "", CI);
+              if (Length->getType() != Type::getInt32Ty(Context)) {
+                Length = new TruncInst(Length, Type::getInt32Ty(Context), "", CI);
+              }
+              CI->replaceAllUsesWith(Length);
+              CI->eraseFromParent(); 
+            }
+          }
+        }
+    }
+  }
+
+  Changed |= !RemoveSet.empty();
+  for (InstSet::iterator I = RemoveSet.begin(),
+       E = RemoveSet.end(); I != E; ++I) {
+    (*I)->eraseFromParent();
+  }
+
+  return Changed;
+}
+
+
+FunctionPass* createLowerMagicPass() {
+  return new LowerMagic();
+}
+
+}
+#endif





More information about the vmkit-commits mailing list