diff --git a/frontend/lib/resolution/prims.cpp b/frontend/lib/resolution/prims.cpp index c4d4e76a17d0..f993f6840d6d 100644 --- a/frontend/lib/resolution/prims.cpp +++ b/frontend/lib/resolution/prims.cpp @@ -705,7 +705,6 @@ CallResolutionResult resolvePrimCall(Context* context, type = primFieldByNum(context, ci); break; - case PRIM_CLASS_NAME_BY_ID: case PRIM_ITERATOR_RECORD_FIELD_VALUE_BY_FORMAL: case PRIM_IS_GENERIC_TYPE: case PRIM_IS_CLASS_TYPE: @@ -725,11 +724,10 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_IS_CONST_COPYABLE: case PRIM_IS_ASSIGNABLE: case PRIM_IS_CONST_ASSIGNABLE: - case PRIM_HAS_DEFAULT_VALUE: - case PRIM_NEEDS_AUTO_DESTROY: + case PRIM_HAS_DEFAULT_VALUE: // param uses in module code + case PRIM_NEEDS_AUTO_DESTROY: // param uses in module code CHPL_UNIMPL("various primitives"); break; - case PRIM_CALL_RESOLVES: case PRIM_CALL_AND_FN_RESOLVES: case PRIM_METHOD_CALL_AND_FN_RESOLVES: @@ -886,6 +884,7 @@ CallResolutionResult resolvePrimCall(Context* context, BoolParam::get(context, isEqual)); break; } + case PRIM_IS_WIDE_PTR: case PRIM_NOTEQUAL: case PRIM_LESSOREQUAL: case PRIM_GREATEROREQUAL: @@ -930,12 +929,23 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_POW: case PRIM_MIN: case PRIM_MAX: + case PRIM_STEAL: if (ci.numActuals() > 0) { type = QualifiedType(QualifiedType::CONST_VAR, ci.actual(0).type().type()); } break; - + /* primitives that return default int */ + case PRIM_GET_UNION_ID: + case PRIM_GET_REQUESTED_SUBLOC: + type = QualifiedType(QualifiedType::CONST_VAR, + IntType::get(context, 0)); + break; + /* primitives that return an int32 */ + case PRIM_GETCID: + type = QualifiedType(QualifiedType::CONST_VAR, + IntType::get(context, 32)); + break; /* primitives that return void */ case PRIM_NOOP: case PRIM_MOVE: @@ -992,6 +1002,19 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_INVARIANT_START: case PRIM_GET_TEST_BY_NAME: case PRIM_GET_TEST_BY_INDEX: + case PRIM_ARRAY_SET: + case PRIM_ARRAY_SET_FIRST: + case PRIM_INIT_FIELDS: + case PRIM_CHPL_COMM_GET: + case PRIM_CHPL_COMM_PUT: + case PRIM_CHPL_COMM_ARRAY_GET: + case PRIM_CHPL_COMM_ARRAY_PUT: + case PRIM_CHPL_COMM_REMOTE_PREFETCH: + case PRIM_CHPL_COMM_GET_STRD: + case PRIM_CHPL_COMM_PUT_STRD: + case PRIM_ARRAY_SHIFT_BASE_POINTER: + case PRIM_AUTO_DESTROY_RUNTIME_TYPE: + case PRIM_CREATE_FN_TYPE: type = QualifiedType(QualifiedType::CONST_VAR, VoidType::get(context)); break; @@ -1016,11 +1039,20 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_GET_IMAG: type = primComplexGetComponent(context, ci); break; + case PRIM_WIDE_GET_ADDR: + type = QualifiedType(QualifiedType::CONST_VAR, + CPtrType::getCVoidPtrType(context)); + break; + /* primitives that return a c_string*/ + case PRIM_LOOKUP_FILENAME: + case PRIM_CLASS_NAME_BY_ID: + case PRIM_REF_TO_STRING:{ + type = QualifiedType(QualifiedType::CONST_VAR, + CStringType::get(context)); + break; + } /* primitives that are not yet handled in dyno */ case PRIM_ACTUALS_LIST: - case PRIM_REF_TO_STRING: - case PRIM_GETCID: - case PRIM_GET_UNION_ID: case PRIM_GET_MEMBER: case PRIM_GET_MEMBER_VALUE: case PRIM_NEW: @@ -1057,9 +1089,8 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_GPU_SET_BLOCKSIZE: case PRIM_ASSERT_ON_GPU: case PRIM_GPU_ELIGIBLE: - case PRIM_SIZEOF_BUNDLE: - case PRIM_SIZEOF_DDATA_ELEMENT: - case PRIM_INIT_FIELDS: + case PRIM_SIZEOF_BUNDLE: // TODO: this should be sizeType + case PRIM_SIZEOF_DDATA_ELEMENT: // TODO: this should be sizeType case PRIM_LIFETIME_OF: CHPL_UNIMPL("misc primitives"); break; @@ -1079,17 +1110,7 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_USED_MODULES_LIST: case PRIM_REFERENCED_MODULES_LIST: case PRIM_TUPLE_EXPAND: - case PRIM_CHPL_COMM_GET: - case PRIM_CHPL_COMM_PUT: - case PRIM_CHPL_COMM_ARRAY_GET: - case PRIM_CHPL_COMM_ARRAY_PUT: - case PRIM_CHPL_COMM_REMOTE_PREFETCH: - case PRIM_CHPL_COMM_GET_STRD: - case PRIM_CHPL_COMM_PUT_STRD: case PRIM_ARRAY_GET: - case PRIM_ARRAY_SHIFT_BASE_POINTER: - case PRIM_ARRAY_SET: - case PRIM_ARRAY_SET_FIRST: case PRIM_MAYBE_LOCAL_THIS: case PRIM_MAYBE_LOCAL_ARR_ELEM: case PRIM_MAYBE_AGGREGATE_ASSIGN: @@ -1110,17 +1131,13 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_LOGICAL_FOLDER: case PRIM_WIDE_MAKE: case PRIM_WIDE_GET_LOCALE: - case PRIM_WIDE_GET_NODE: - case PRIM_WIDE_GET_ADDR: - case PRIM_IS_WIDE_PTR: + case PRIM_WIDE_GET_NODE: // TODO: this should be nodeIdType (int32) case PRIM_ON_LOCALE_NUM: - case PRIM_GET_REQUESTED_SUBLOC: case PRIM_REGISTER_GLOBAL_VAR: case PRIM_BROADCAST_GLOBAL_VARS: case PRIM_PRIVATE_BROADCAST: case PRIM_CAPTURE_FN: case PRIM_CAPTURE_FN_TO_CLASS: - case PRIM_CREATE_FN_TYPE: case PRIM_GET_USER_LINE: case PRIM_GET_USER_FILE: case PRIM_RESOLUTION_POINT: @@ -1130,17 +1147,14 @@ CallResolutionResult resolvePrimCall(Context* context, case PRIM_VIRTUAL_METHOD_CALL: case PRIM_END_OF_STATEMENT: case PRIM_CURRENT_ERROR: - case PRIM_STEAL: - case PRIM_AUTO_DESTROY_RUNTIME_TYPE: case PRIM_GET_RUNTIME_TYPE_FIELD: - case PRIM_LOOKUP_FILENAME: case PRIM_GET_VISIBLE_SYMBOLS: case PRIM_STACK_ALLOCATE_CLASS: case PRIM_ZIP: case PRIM_NO_ALIAS_SET: case PRIM_COPIES_NO_ALIAS_SET: case PRIM_OPTIMIZATION_INFO: - case PRIM_GATHER_TESTS: + case PRIM_GATHER_TESTS: // param uses in module code CHPL_UNIMPL("misc primitives"); break; diff --git a/frontend/test/resolution/CMakeLists.txt b/frontend/test/resolution/CMakeLists.txt index b19c14e2c09f..d80dd073be28 100644 --- a/frontend/test/resolution/CMakeLists.txt +++ b/frontend/test/resolution/CMakeLists.txt @@ -64,6 +64,7 @@ comp_unit_test(testReflection) comp_unit_test(testResolve) comp_unit_test(testResolverVerboseErrors) comp_unit_test(testReturnTypes) +comp_unit_test(testRuntimePrimitives) comp_unit_test(testScopeResolve) comp_unit_test(testScopeTypes) comp_unit_test(testSplitInit) diff --git a/frontend/test/resolution/testFunctionCalls.cpp b/frontend/test/resolution/testFunctionCalls.cpp index 55109a047746..b80c24e48789 100644 --- a/frontend/test/resolution/testFunctionCalls.cpp +++ b/frontend/test/resolution/testFunctionCalls.cpp @@ -132,114 +132,11 @@ static void test3b() { helpTest3(theFunction); } -// test that we can handle non-param string for string_length_bytes -static void test4() { - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var s:string; - var x = __primitive("string_length_bytes", s); - )""""); - assert(qt.kind() == QualifiedType::CONST_VAR); - auto typePtr = qt.type(); - assert(typePtr); - assert(typePtr->isIntType()); - assert(typePtr->toIntType()->bitwidth() == 64); -} - -// test that we can handle non-param bytes for string_length_bytes -static void test5() { - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var b:bytes; - var x = __primitive("string_length_bytes", b); - )""""); - assert(qt.kind() == QualifiedType::CONST_VAR); - auto typePtr = qt.type(); - assert(typePtr); - assert(typePtr->isIntType()); - assert(typePtr->toIntType()->bitwidth() == 64); -} - -static void test6() { - // test for primitive return type for get real/imag - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var a: complex(128); - var x = __primitive("complex_get_real", a); - )""""); - assert(qt.kind() == QualifiedType::REF); - auto typePtr = qt.type(); - assert(typePtr); - auto realPtr = typePtr->toRealType(); - assert(realPtr->bitwidth()==64); -} - -static void test7() { - // test for primitive return type for get real/imag - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var a: complex(64); - var x = __primitive("complex_get_real", a); - )""""); - assert(qt.kind() == QualifiedType::REF); - auto typePtr = qt.type(); - assert(typePtr); - auto realPtr = typePtr->toRealType(); - assert(realPtr->bitwidth()==32); -} - -static void test8() { - // test for primitive return type for get real/imag - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var a: complex(128); - var x = __primitive("complex_get_imag", a); - )""""); - assert(qt.kind() == QualifiedType::REF); - auto typePtr = qt.type(); - assert(typePtr); - auto realPtr = typePtr->toRealType(); - assert(realPtr->bitwidth()==64); -} - -static void test9() { - // test for primitive return type for get real/imag - Context ctx; - auto context = &ctx; - QualifiedType qt = resolveTypeOfXInit(context, - R""""( - var a: complex(64); - var x = __primitive("complex_get_imag", a); - )""""); - assert(qt.kind() == QualifiedType::REF); - auto typePtr = qt.type(); - assert(typePtr); - auto realPtr = typePtr->toRealType(); - assert(realPtr->bitwidth()==32); -} - - int main() { test1(); test2(); test3a(); test3b(); - test4(); - test5(); - test6(); - test7(); - test8(); - test9(); return 0; } diff --git a/frontend/test/resolution/testRuntimePrimitives.cpp b/frontend/test/resolution/testRuntimePrimitives.cpp new file mode 100644 index 000000000000..1c9475505be7 --- /dev/null +++ b/frontend/test/resolution/testRuntimePrimitives.cpp @@ -0,0 +1,318 @@ +/* + * Copyright 2021-2023 Hewlett Packard Enterprise Development LP + * Other additional copyright holders may be indicated within. + * + * The entirety of this work is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test-resolution.h" + +#include "chpl/types/all-types.h" + + +static void voidTypeTestHelper(std::string program) { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, program); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isVoidType()); +} + +// tests for primitives that should return void +static void testVoidPrims() { + // test for primitive "chpl_init_record" + voidTypeTestHelper(R"""(var x = __primitive("chpl_init_record");)"""); + + // test for primitive "chpl_comm_get" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_get");)"""); + + // test for primitive "chpl_comm_put" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_put");)"""); + + // test for primitive "chpl_comm_array_get" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_array_get");)"""); + + // test for primitive "chpl_comm_array_put" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_array_put");)"""); + + // test for primitive "chpl_comm_remote_prefetch" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_remote_prefetch");)"""); + + // test for primitive "chpl_comm_get_strd" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_get_strd");)"""); + + // test for primitive "chpl_comm_put_strd" + voidTypeTestHelper(R"""(var x = __primitive("chpl_comm_put_strd");)"""); + + // test for primitive "shift_base_pointer" + voidTypeTestHelper(R"""(var x = __primitive("shift_base_pointer");)"""); + + // test for primitive "array_set" + voidTypeTestHelper(R"""(var x = __primitive("array_set");)"""); + + // test for primitive "array_set_first" + voidTypeTestHelper(R"""(var x = __primitive("array_set_first");)"""); + + // test for primitive "auto destroy runtime type" + voidTypeTestHelper(R"""(var x = __primitive("auto destroy runtime type");)"""); + + // test for primitive "create fn type" + voidTypeTestHelper(R"""(var x = __primitive("create fn type");)"""); +} + +// test that we can handle non-param string for string_length_bytes +static void test1() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var s:string; + var x = __primitive("string_length_bytes", s); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); + assert(typePtr->toIntType()->bitwidth() == 64); +} + +// test that we can handle non-param bytes for string_length_bytes +static void test2() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var b:bytes; + var x = __primitive("string_length_bytes", b); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); + assert(typePtr->toIntType()->bitwidth() == 64); +} + +static void test3() { + // test for primitive return type for get real/imag + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var a: complex(128); + var x = __primitive("complex_get_real", a); + )""""); + assert(qt.kind() == QualifiedType::REF); + auto typePtr = qt.type(); + assert(typePtr); + auto realPtr = typePtr->toRealType(); + assert(realPtr->bitwidth()==64); +} + +static void test4() { + // test for primitive return type for get real/imag + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var a: complex(64); + var x = __primitive("complex_get_real", a); + )""""); + assert(qt.kind() == QualifiedType::REF); + auto typePtr = qt.type(); + assert(typePtr); + auto realPtr = typePtr->toRealType(); + assert(realPtr->bitwidth()==32); +} + +static void test5() { + // test for primitive return type for get real/imag + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var a: complex(128); + var x = __primitive("complex_get_imag", a); + )""""); + assert(qt.kind() == QualifiedType::REF); + auto typePtr = qt.type(); + assert(typePtr); + auto realPtr = typePtr->toRealType(); + assert(realPtr->bitwidth()==64); +} + +static void test6() { + // test for primitive return type for get real/imag + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var a: complex(64); + var x = __primitive("complex_get_imag", a); + )""""); + assert(qt.kind() == QualifiedType::REF); + auto typePtr = qt.type(); + assert(typePtr); + auto realPtr = typePtr->toRealType(); + assert(realPtr->bitwidth()==32); +} + +static void test7() { + // test for primitive "is wide pointer", which should return a bool + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var x = __primitive("is wide pointer"); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isBoolType()); +} + +// test for primitive "_wide_get_addr", which should return a void ptr +static void test8() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var x = __primitive("_wide_get_addr"); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + auto cPtrType = typePtr->toCPtrType(); + assert(cPtrType); + assert(cPtrType->isVoidPtr()); +} + +// test for primitive "steal", which should return the type of the argument +static void test9() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var a = 1; + var x = __primitive("steal", a); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); +} + +// test for primitive "getcid", which should return an int32 +static void test10() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var x = __primitive("getcid"); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); + assert(typePtr->toIntType()->bitwidth() == 32); +} + +// test for primitive "get_union_id", which should return a default int +static void test11() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R""""( + var x = __primitive("get_union_id"); + )""""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); + assert(typePtr->toIntType()->bitwidth() == 64); +} + + +// "chpl_task_getRequestedSubloc", which should return int 64 +static void test12() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R"""(var x = __primitive("chpl_task_getRequestedSubloc");)"""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isIntType()); + assert(typePtr->toIntType()->bitwidth() == 64); +} + +// "class name by id", which should return a cString +static void test13() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R"""(var x = __primitive("class name by id");)"""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isCStringType()); +} + +// "ref to string", which should return a cString +static void test14() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R"""(var x = __primitive("ref to string");)"""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isCStringType()); +} + +// "chpl_lookupFilename", which should return a cString +static void test15() { + Context ctx; + auto context = &ctx; + QualifiedType qt = resolveTypeOfXInit(context, + R"""(var x = __primitive("chpl_lookupFilename");)"""); + assert(qt.kind() == QualifiedType::CONST_VAR); + auto typePtr = qt.type(); + assert(typePtr); + assert(typePtr->isCStringType()); +} + + +int main() { + testVoidPrims(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + + return 0; +}