diff --git a/compiler/ilgen/OMRVirtualMachineRegister.cpp b/compiler/ilgen/OMRVirtualMachineRegister.cpp index 7d0f521bd4..45c24a2e7f 100644 --- a/compiler/ilgen/OMRVirtualMachineRegister.cpp +++ b/compiler/ilgen/OMRVirtualMachineRegister.cpp @@ -42,14 +42,11 @@ OMR::VirtualMachineRegister::VirtualMachineRegister( _integerTypeForAdjustments = pointerToRegisterType->baseType(); if (_integerTypeForAdjustments->isPointer()) { - _integerTypeForAdjustments = _integerTypeForAdjustments->baseType(); - if (_integerTypeForAdjustments->isPointer()) - { - _integerTypeForAdjustments = b->typeDictionary()->getWord(); - } - TR_ASSERT(adjustByStep == _integerTypeForAdjustments->getSize(), + TR::IlType *baseType = _integerTypeForAdjustments->baseType(); + _integerTypeForAdjustments = b->typeDictionary()->getWord(); + TR_ASSERT(adjustByStep == baseType->getSize(), "VirtualMachineRegister for %s adjustByStep (%u) != size represented by pointerToRegisterType (%u)", - localName, _adjustByStep, _integerTypeForAdjustments->getSize()); + localName, _adjustByStep, baseType->getSize()); _isAdjustable = true; } else diff --git a/compiler/ilgen/OMRVirtualMachineRegister.hpp b/compiler/ilgen/OMRVirtualMachineRegister.hpp index 755a16e644..128a91aafe 100644 --- a/compiler/ilgen/OMRVirtualMachineRegister.hpp +++ b/compiler/ilgen/OMRVirtualMachineRegister.hpp @@ -160,7 +160,8 @@ class VirtualMachineRegister : public TR::VirtualMachineState */ virtual void Adjust(TR::IlBuilder *b, TR::IlValue *amount) { - TR::IlValue *off=b->Mul(amount, + TR::IlValue *off=b->Mul( + b-> ConvertTo(_integerTypeForAdjustments, amount), b-> ConstInteger(_integerTypeForAdjustments, _adjustByStep)); adjust(b, off); } @@ -172,7 +173,7 @@ class VirtualMachineRegister : public TR::VirtualMachineState * Adjust() is really a convenience function for the common operation of adding a value to the register. More * complicated operations (e.g. multiplying the value) can be built using Load() and Store() if needed. */ - virtual void Adjust(TR::IlBuilder *b, int64_t amount) + virtual void Adjust(TR::IlBuilder *b, size_t amount) { adjust(b, b->ConstInteger(_integerTypeForAdjustments, amount * _adjustByStep)); } diff --git a/compiler/ilgen/OMRVirtualMachineRegisterInStruct.hpp b/compiler/ilgen/OMRVirtualMachineRegisterInStruct.hpp index fb6aa76763..2dd33def32 100644 --- a/compiler/ilgen/OMRVirtualMachineRegisterInStruct.hpp +++ b/compiler/ilgen/OMRVirtualMachineRegisterInStruct.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 IBM Corp. and others + * Copyright (c) 2016, 2019 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -74,13 +74,10 @@ class VirtualMachineRegisterInStruct : public TR::VirtualMachineRegister _integerTypeForAdjustments = b->typeDictionary()->GetFieldType(structName, fieldName); if (_integerTypeForAdjustments->isPointer()) { - _integerTypeForAdjustments = _integerTypeForAdjustments->baseType(); - if (_integerTypeForAdjustments->isPointer()) - { - _integerTypeForAdjustments = b->typeDictionary()->getWord(); - } + TR::IlType *baseType = _integerTypeForAdjustments->baseType(); + _integerTypeForAdjustments = b->typeDictionary()->getWord(); _isAdjustable = true; - _adjustByStep = _integerTypeForAdjustments->getSize(); + _adjustByStep = baseType->getSize(); } else { diff --git a/jitbuilder/apigen/jitbuilder.api.json b/jitbuilder/apigen/jitbuilder.api.json index 0b856ebd4d..dc385214d8 100644 --- a/jitbuilder/apigen/jitbuilder.api.json +++ b/jitbuilder/apigen/jitbuilder.api.json @@ -2220,7 +2220,7 @@ , "return": "none" , "parms": [ {"name":"b","type":"IlBuilder"}, - {"name":"amount","type":"int64"} + {"name":"amount","type":"unsignedInteger"} ] }, { "name": "Load" diff --git a/jitbuilder/release/CMakeLists.txt b/jitbuilder/release/CMakeLists.txt index 8868e9a831..56499b97b9 100644 --- a/jitbuilder/release/CMakeLists.txt +++ b/jitbuilder/release/CMakeLists.txt @@ -62,6 +62,7 @@ if(OMR_JITBUILDER_TEST_EXTENDED) create_jitbuilder_test(tableswitch cpp/samples/TableSwitch.cpp) create_jitbuilder_test(toiltype cpp/samples/ToIlType.cpp) create_jitbuilder_test(union cpp/samples/Union.cpp) + create_jitbuilder_test(vmregister cpp/samples/VMRegister.cpp) endif() # Experimental Tests: These are still on the experimental side diff --git a/jitbuilder/release/cpp/Makefile b/jitbuilder/release/cpp/Makefile index 92544e0d90..e5b33a303e 100644 --- a/jitbuilder/release/cpp/Makefile +++ b/jitbuilder/release/cpp/Makefile @@ -57,6 +57,7 @@ ALL_TESTS = \ toiltype \ transactionaloperations \ union \ + vmregister \ worklist \ # Compile all the tests by default @@ -94,6 +95,7 @@ all_goal: common_goal ./thunks ./toiltype ./union + ./vmregister # Tests that are still on the experimental side # If you add to this list and want them to be built under "make", please @@ -302,6 +304,12 @@ union : $(LIBJITBUILDER) Union.o Union.o: $(SAMPLE_SRC)/Union.cpp $(SAMPLE_SRC)/Union.hpp $(CXX) -o $@ $(CXXFLAGS) $< + +vmregister : $(LIBJITBUILDER) VMRegister.o + $(CXX) -g -fno-rtti -o $@ VMRegister.o -L$(LIBJITBUILDERDIR) -ljitbuilder -ldl + +VMRegister.o: $(SAMPLE_SRC)/VMRegister.cpp $(SAMPLE_SRC)/VMRegister.hpp + $(CXX) -o $@ $(CXXFLAGS) $< worklist : $(LIBJITBUILDER) Worklist.o $(CXX) -g -fno-rtti -o $@ Worklist.o -L$(LIBJITBUILDERDIR) -ljitbuilder -ldl diff --git a/jitbuilder/release/cpp/samples/VMRegister.cpp b/jitbuilder/release/cpp/samples/VMRegister.cpp new file mode 100644 index 0000000000..7f8696256b --- /dev/null +++ b/jitbuilder/release/cpp/samples/VMRegister.cpp @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2016, 2019 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + + +#include +#include +#include +#include + +#include "VMRegister.hpp" +#include "JitBuilder.hpp" + +using std::cout; +using std::cerr; + +#define TOSTR(x) #x +#define LINETOSTR(x) TOSTR(x) + + +int +main(int argc, char *argv[]) + { + cout << "Step 1: initialize JIT\n"; + bool initialized = initializeJit(); + if (!initialized) + { + cerr << "FAIL: could not initialize JIT\n"; + exit(-1); + } + + cout << "Step 2: define type dictionary\n"; + OMR::JitBuilder::TypeDictionary types; + + cout << "Step 3: compile vmregister method builder\n"; + VMRegisterMethod method(&types); + void *entry = 0; + int32_t rc = compileMethodBuilder(&method, &entry); + if (rc != 0) + { + cerr << "FAIL: compilation error " << rc << "\n"; + exit(-2); + } + + cout << "Step 4: invoke compiled vmregister function and print results\n"; + typedef int32_t (VMRegisterMethodFunction)(int8_t **values, int32_t count); + VMRegisterMethodFunction *vmregister = (VMRegisterMethodFunction *) entry; + + int8_t values[] = {7,2,9,5,3,1,6}; + int8_t *vals = values; + int32_t retVal = vmregister(&vals, 7); + cout << "vmregister(values) returned " << retVal << "\n"; + + cout << "Step 5: compile vmregisterInStruct method builder\n"; + VMRegisterInStructMethod method2(&types); + entry = 0; + rc = compileMethodBuilder(&method2, &entry); + if (rc != 0) + { + cerr << "FAIL: compilation error " << rc << "\n"; + exit(-2); + } + + cout << "Step 6: invoke compiled vmregisterInStruct function and print results\n"; + typedef int32_t (VMRegisterInStructMethodFunction)(VMRegisterStruct *param); + VMRegisterInStructMethodFunction *vmregisterInStruct = (VMRegisterInStructMethodFunction *) entry; + + VMRegisterStruct param; + param.count = 7; + param.values = values; + retVal = vmregisterInStruct(¶m); + cout << "vmregisterInStruct(values) returned " << retVal << "\n"; + + cout << "Step 7: shutdown JIT\n"; + shutdownJit(); + } + + + +VMRegisterMethod::VMRegisterMethod(OMR::JitBuilder::TypeDictionary *d) + : OMR::JitBuilder::MethodBuilder(d, (OMR::JitBuilder::VirtualMachineState *) NULL) + { + DefineLine(LINETOSTR(__LINE__)); + DefineFile(__FILE__); + + DefineName("vmregister"); + DefineParameter("valuesPtr", d->PointerTo(d->PointerTo(Int8))); + DefineParameter("count", Int32); + DefineReturnType(Int32); + } + +bool +VMRegisterMethod::buildIL() + { + OMR::JitBuilder::TypeDictionary *dict = typeDictionary(); + OMR::JitBuilder::IlType *pElementType = dict->PointerTo(Int8); + OMR::JitBuilder::IlType *ppElementType = dict->PointerTo(pElementType); + OMR::JitBuilder::VirtualMachineRegister *vmreg = new OMR::JitBuilder::VirtualMachineRegister(this, "MYBYTES", ppElementType, sizeof(int8_t), Load("valuesPtr")); + + Store("result", ConstInt32(0)); + + OMR::JitBuilder::IlBuilder *loop = NULL; + ForLoopUp("i", &loop, + ConstInt32(0), + Load("count"), + ConstInt32(1)); + + loop->Store("valAddress", + vmreg->Load(loop)); + + loop->Store("val", + loop-> LoadAt(pElementType, + loop-> Load("valAddress"))); + + loop->Store("result", + loop-> Add( + loop-> Load("result"), + loop-> ConvertTo(Int32, + loop-> Load("val")))); + vmreg->Adjust(loop, 1); + + Return(Load("result")); + + return true; + } + +VMRegisterInStructMethod::VMRegisterInStructMethod(OMR::JitBuilder::TypeDictionary *d) + : OMR::JitBuilder::MethodBuilder(d, (OMR::JitBuilder::VirtualMachineState *) NULL) + { + DefineLine(LINETOSTR(__LINE__)); + DefineFile(__FILE__); + + d->DefineStruct("VMRegisterStruct"); + d->DefineField("VMRegisterStruct", "values", d->PointerTo(Int8), offsetof(VMRegisterStruct, values)); + d->DefineField("VMRegisterStruct", "count", Int32, offsetof(VMRegisterStruct, count)); + d->CloseStruct("VMRegisterStruct"); + + DefineName("vmregisterInStruct"); + DefineParameter("param", d->PointerTo("VMRegisterStruct")); + DefineReturnType(Int32); + } + +bool +VMRegisterInStructMethod::buildIL() + { + OMR::JitBuilder::TypeDictionary *dict = typeDictionary(); + OMR::JitBuilder::IlType *pElementType = dict->PointerTo(Int8); + OMR::JitBuilder::IlType *ppElementType = dict->PointerTo(pElementType); + OMR::JitBuilder::VirtualMachineRegisterInStruct *vmreg = new OMR::JitBuilder::VirtualMachineRegisterInStruct(this, "VMRegisterStruct", "param", "values", "VALUES"); + + Store("count", + LoadIndirect("VMRegisterStruct", "count", + Load("param"))); + + Store("result", ConstInt32(0)); + + OMR::JitBuilder::IlBuilder *loop = NULL; + ForLoopUp("i", &loop, + ConstInt32(0), + Load("count"), + ConstInt32(1)); + + loop->Store("valAddress", + vmreg->Load(loop)); + + loop->Store("val", + loop-> LoadAt(pElementType, + loop-> Load("valAddress"))); + + loop->Store("result", + loop-> Add( + loop-> Load("result"), + loop-> ConvertTo(Int32, + loop-> Load("val")))); + vmreg->Adjust(loop, 1); + + Return(Load("result")); + + return true; + } diff --git a/jitbuilder/release/cpp/samples/VMRegister.hpp b/jitbuilder/release/cpp/samples/VMRegister.hpp new file mode 100644 index 0000000000..bcdaaacaca --- /dev/null +++ b/jitbuilder/release/cpp/samples/VMRegister.hpp @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2016, 2019 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + + +#ifndef VMREGISTER_INCL +#define VMREGISTER_INCL + +#include "JitBuilder.hpp" + +class VMRegisterMethod : public OMR::JitBuilder::MethodBuilder + { + public: + VMRegisterMethod(OMR::JitBuilder::TypeDictionary *); + virtual bool buildIL(); + }; + +typedef struct VMRegisterStruct { + int8_t *values; + int32_t count; +} VMRegisterStruct; + +class VMRegisterInStructMethod : public OMR::JitBuilder::MethodBuilder + { + public: + VMRegisterInStructMethod(OMR::JitBuilder::TypeDictionary *); + virtual bool buildIL(); + }; + +#endif // !defined(VMREGISTER_INCL)