blob: 38944820c0535d1aed0d981b180349cadaac7d32 [file] [log] [blame]
//===----- LowerConstantCalls.cpp - Changes arrayLength calls --------------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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();
}
}