brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.8 KiB · 28d5eb7 Raw
355 lines · cpp
1//===- FIRTypesTest.cpp ---------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10#include "flang/Optimizer/Dialect/FIRType.h"11#include "flang/Optimizer/Dialect/Support/KindMapping.h"12#include "flang/Optimizer/Support/InitFIR.h"13 14struct FIRTypesTest : public testing::Test {15public:16  void SetUp() {17    fir::support::loadDialects(context);18    kindMap = new fir::KindMapping(&context, kindMapInit, "r42a10c14d28i40l41");19  }20  mlir::MLIRContext context;21  fir::KindMapping *kindMap{};22  std::string kindMapInit =23      "i10:80,l3:24,a1:8,r54:Double,r62:X86_FP80,r11:PPC_FP128";24};25 26// Test fir::isPolymorphicType from flang/Optimizer/Dialect/FIRType.h.27TEST_F(FIRTypesTest, isPolymorphicTypeTest) {28  mlir::Type noneTy = mlir::NoneType::get(&context);29  mlir::Type seqNoneTy =30      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy);31  mlir::Type recTy = fir::RecordType::get(&context, "dt");32  mlir::Type seqRecTy =33      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);34 35  // CLASS(T)36  mlir::Type ty = fir::ClassType::get(recTy);37  EXPECT_TRUE(fir::isPolymorphicType(ty));38  EXPECT_TRUE(fir::isPolymorphicType(fir::ReferenceType::get(ty)));39 40  // CLASS(T), DIMENSION(10)41  ty = fir::ClassType::get(fir::SequenceType::get({10}, recTy));42  EXPECT_TRUE(fir::isPolymorphicType(ty));43 44  // CLASS(T), DIMENSION(:)45  ty = fir::ClassType::get(seqRecTy);46  EXPECT_TRUE(fir::isPolymorphicType(ty));47 48  // CLASS(T), ALLOCATABLE49  ty = fir::ClassType::get(fir::HeapType::get(recTy));50  EXPECT_TRUE(fir::isPolymorphicType(ty));51 52  // CLASS(T), ALLOCATABLE, DIMENSION(:)53  ty = fir::ClassType::get(fir::HeapType::get(seqRecTy));54  EXPECT_TRUE(fir::isPolymorphicType(ty));55 56  // CLASS(T), POINTER57  ty = fir::ClassType::get(fir::PointerType::get(recTy));58  EXPECT_TRUE(fir::isPolymorphicType(ty));59 60  // CLASS(T), POINTER, DIMENSIONS(:)61  ty = fir::ClassType::get(fir::PointerType::get(seqRecTy));62  EXPECT_TRUE(fir::isPolymorphicType(ty));63 64  // CLASS(*)65  ty = fir::ClassType::get(noneTy);66  EXPECT_TRUE(fir::isPolymorphicType(ty));67  EXPECT_TRUE(fir::isPolymorphicType(fir::ReferenceType::get(ty)));68 69  // TYPE(*)70  EXPECT_TRUE(fir::isPolymorphicType(fir::BoxType::get(noneTy)));71 72  // TYPE(*), DIMENSION(:)73  EXPECT_TRUE(fir::isPolymorphicType(fir::BoxType::get(seqNoneTy)));74 75  // false tests76  EXPECT_FALSE(fir::isPolymorphicType(noneTy));77  EXPECT_FALSE(fir::isPolymorphicType(seqNoneTy));78}79 80// Test fir::isUnlimitedPolymorphicType from flang/Optimizer/Dialect/FIRType.h.81TEST_F(FIRTypesTest, isUnlimitedPolymorphicTypeTest) {82  mlir::Type noneTy = mlir::NoneType::get(&context);83  mlir::Type seqNoneTy =84      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy);85 86  // CLASS(*)87  mlir::Type ty = fir::ClassType::get(noneTy);88  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));89  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::ReferenceType::get(ty)));90 91  // CLASS(*), DIMENSION(10)92  ty = fir::ClassType::get(fir::SequenceType::get({10}, noneTy));93  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));94 95  // CLASS(*), DIMENSION(:)96  ty = fir::ClassType::get(97      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy));98  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));99 100  // CLASS(*), ALLOCATABLE101  ty = fir::ClassType::get(fir::HeapType::get(noneTy));102  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));103 104  // CLASS(*), ALLOCATABLE, DIMENSION(:)105  ty = fir::ClassType::get(fir::HeapType::get(seqNoneTy));106  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));107 108  // CLASS(*), POINTER109  ty = fir::ClassType::get(fir::PointerType::get(noneTy));110  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));111 112  // CLASS(*), POINTER, DIMENSIONS(:)113  ty = fir::ClassType::get(fir::PointerType::get(seqNoneTy));114  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));115 116  // TYPE(*)117  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::BoxType::get(noneTy)));118 119  // TYPE(*), DIMENSION(:)120  EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::BoxType::get(seqNoneTy)));121 122  // false tests123  EXPECT_FALSE(fir::isUnlimitedPolymorphicType(noneTy));124  EXPECT_FALSE(fir::isUnlimitedPolymorphicType(seqNoneTy));125}126 127// Test fir::isBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.128TEST_F(FIRTypesTest, isBoxedRecordType) {129  mlir::Type recTy = fir::RecordType::get(&context, "dt");130  mlir::Type seqRecTy =131      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);132  mlir::Type ty = fir::BoxType::get(recTy);133  EXPECT_TRUE(fir::isBoxedRecordType(ty));134  EXPECT_TRUE(fir::isBoxedRecordType(fir::ReferenceType::get(ty)));135 136  // TYPE(T), ALLOCATABLE137  ty = fir::BoxType::get(fir::HeapType::get(recTy));138  EXPECT_TRUE(fir::isBoxedRecordType(ty));139 140  // TYPE(T), POINTER141  ty = fir::BoxType::get(fir::PointerType::get(recTy));142  EXPECT_TRUE(fir::isBoxedRecordType(ty));143 144  // TYPE(T), DIMENSION(10)145  ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));146  EXPECT_TRUE(fir::isBoxedRecordType(ty));147 148  // TYPE(T), DIMENSION(:)149  ty = fir::BoxType::get(seqRecTy);150  EXPECT_TRUE(fir::isBoxedRecordType(ty));151 152  EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(153      fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));154}155 156// Test fir::isScalarBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.157TEST_F(FIRTypesTest, isScalarBoxedRecordType) {158  mlir::Type recTy = fir::RecordType::get(&context, "dt");159  mlir::Type seqRecTy =160      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);161  mlir::Type ty = fir::BoxType::get(recTy);162  EXPECT_TRUE(fir::isScalarBoxedRecordType(ty));163  EXPECT_TRUE(fir::isScalarBoxedRecordType(fir::ReferenceType::get(ty)));164 165  // CLASS(T), ALLOCATABLE166  ty = fir::ClassType::get(fir::HeapType::get(recTy));167  EXPECT_TRUE(fir::isScalarBoxedRecordType(ty));168 169  // TYPE(T), ALLOCATABLE170  ty = fir::BoxType::get(fir::HeapType::get(recTy));171  EXPECT_TRUE(fir::isScalarBoxedRecordType(ty));172 173  // TYPE(T), POINTER174  ty = fir::BoxType::get(fir::PointerType::get(recTy));175  EXPECT_TRUE(fir::isScalarBoxedRecordType(ty));176 177  // CLASS(T), POINTER178  ty = fir::ClassType::get(fir::PointerType::get(recTy));179  EXPECT_TRUE(fir::isScalarBoxedRecordType(ty));180 181  // TYPE(T), DIMENSION(10)182  ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));183  EXPECT_FALSE(fir::isScalarBoxedRecordType(ty));184 185  // TYPE(T), DIMENSION(:)186  ty = fir::BoxType::get(seqRecTy);187  EXPECT_FALSE(fir::isScalarBoxedRecordType(ty));188 189  EXPECT_FALSE(fir::isScalarBoxedRecordType(fir::BoxType::get(190      fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));191}192 193TEST_F(FIRTypesTest, updateTypeForUnlimitedPolymorphic) {194  // RecordType are not changed.195 196  // !fir.tyep<T> -> !fir.type<T>197  mlir::Type recTy = fir::RecordType::get(&context, "dt");198  EXPECT_EQ(recTy, fir::updateTypeForUnlimitedPolymorphic(recTy));199 200  // !fir.array<2x!fir.type<T>> -> !fir.array<2x!fir.type<T>>201  mlir::Type arrRecTy = fir::SequenceType::get({2}, recTy);202  EXPECT_EQ(arrRecTy, fir::updateTypeForUnlimitedPolymorphic(arrRecTy));203 204  // !fir.heap<!fir.type<T>> -> !fir.heap<!fir.type<T>>205  mlir::Type heapTy = fir::HeapType::get(recTy);206  EXPECT_EQ(heapTy, fir::updateTypeForUnlimitedPolymorphic(heapTy));207  // !fir.heap<!fir.array<2x!fir.type<T>>> ->208  // !fir.heap<!fir.array<2x!fir.type<T>>>209  mlir::Type heapArrTy = fir::HeapType::get(arrRecTy);210  EXPECT_EQ(heapArrTy, fir::updateTypeForUnlimitedPolymorphic(heapArrTy));211 212  // !fir.ptr<!fir.type<T>> -> !fir.ptr<!fir.type<T>>213  mlir::Type ptrTy = fir::PointerType::get(recTy);214  EXPECT_EQ(ptrTy, fir::updateTypeForUnlimitedPolymorphic(ptrTy));215  // !fir.ptr<!fir.array<2x!fir.type<T>>> ->216  // !fir.ptr<!fir.array<2x!fir.type<T>>>217  mlir::Type ptrArrTy = fir::PointerType::get(arrRecTy);218  EXPECT_EQ(ptrArrTy, fir::updateTypeForUnlimitedPolymorphic(ptrArrTy));219 220  // When updating intrinsic types the array, pointer and heap types are kept.221  // only the inner element type is changed to `none`.222  mlir::Type none = mlir::NoneType::get(&context);223  mlir::Type arrNone = fir::SequenceType::get({10}, none);224  mlir::Type heapNone = fir::HeapType::get(none);225  mlir::Type heapArrNone = fir::HeapType::get(arrNone);226  mlir::Type ptrNone = fir::PointerType::get(none);227  mlir::Type ptrArrNone = fir::PointerType::get(arrNone);228 229  mlir::Type i32Ty = mlir::IntegerType::get(&context, 32);230  mlir::Type f32Ty = mlir::Float32Type::get(&context);231  mlir::Type l1Ty = fir::LogicalType::get(&context, 1);232  mlir::Type cplx32Ty = mlir::ComplexType::get(f32Ty);233  mlir::Type char1Ty = fir::CharacterType::get(&context, 1, 10);234  llvm::SmallVector<mlir::Type> intrinsicTypes = {235      i32Ty, f32Ty, l1Ty, cplx32Ty, char1Ty};236 237  for (mlir::Type ty : intrinsicTypes) {238    // `ty` -> none239    EXPECT_EQ(none, fir::updateTypeForUnlimitedPolymorphic(ty));240 241    // !fir.array<10xTY> -> !fir.array<10xnone>242    mlir::Type arrTy = fir::SequenceType::get({10}, ty);243    EXPECT_EQ(arrNone, fir::updateTypeForUnlimitedPolymorphic(arrTy));244 245    // !fir.heap<TY> -> !fir.heap<none>246    mlir::Type heapTy = fir::HeapType::get(ty);247    EXPECT_EQ(heapNone, fir::updateTypeForUnlimitedPolymorphic(heapTy));248 249    // !fir.heap<!fir.array<10xTY>> -> !fir.heap<!fir.array<10xnone>>250    mlir::Type heapArrTy = fir::HeapType::get(arrTy);251    EXPECT_EQ(heapArrNone, fir::updateTypeForUnlimitedPolymorphic(heapArrTy));252 253    // !fir.ptr<TY> -> !fir.ptr<none>254    mlir::Type ptrTy = fir::PointerType::get(ty);255    EXPECT_EQ(ptrNone, fir::updateTypeForUnlimitedPolymorphic(ptrTy));256 257    // !fir.ptr<!fir.array<10xTY>> -> !fir.ptr<!fir.array<10xnone>>258    mlir::Type ptrArrTy = fir::PointerType::get(arrTy);259    EXPECT_EQ(ptrArrNone, fir::updateTypeForUnlimitedPolymorphic(ptrArrTy));260  }261}262 263TEST_F(FIRTypesTest, getTypeAsString) {264  EXPECT_EQ("i32",265      fir::getTypeAsString(mlir::IntegerType::get(&context, 32), *kindMap));266  EXPECT_EQ("ref_i32",267      fir::getTypeAsString(268          fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)),269          *kindMap));270  EXPECT_EQ(271      "f64", fir::getTypeAsString(mlir::Float64Type::get(&context), *kindMap));272  EXPECT_EQ(273      "l8", fir::getTypeAsString(fir::LogicalType::get(&context, 1), *kindMap));274  EXPECT_EQ("z32",275      fir::getTypeAsString(276          mlir::ComplexType::get(mlir::Float32Type::get(&context)), *kindMap));277  EXPECT_EQ("c8",278      fir::getTypeAsString(fir::CharacterType::get(&context, 1, 1), *kindMap));279  EXPECT_EQ("c8x10",280      fir::getTypeAsString(fir::CharacterType::get(&context, 1, 10), *kindMap));281  mlir::Type ty = mlir::IntegerType::get(&context, 64);282  mlir::Type arrTy = fir::SequenceType::get({10, 20}, ty);283  EXPECT_EQ("10x20xi64", fir::getTypeAsString(arrTy, *kindMap));284  EXPECT_EQ(285      "idx", fir::getTypeAsString(mlir::IndexType::get(&context), *kindMap));286  EXPECT_EQ("ptr_i32",287      fir::getTypeAsString(288          fir::PointerType::get(mlir::IntegerType::get(&context, 32)),289          *kindMap));290  EXPECT_EQ("heap_i32",291      fir::getTypeAsString(292          fir::HeapType::get(mlir::IntegerType::get(&context, 32)), *kindMap));293  EXPECT_EQ("box_i32",294      fir::getTypeAsString(295          fir::BoxType::get(mlir::IntegerType::get(&context, 32)), *kindMap));296  EXPECT_EQ("class_i32",297      fir::getTypeAsString(298          fir::ClassType::get(mlir::IntegerType::get(&context, 32)), *kindMap));299  EXPECT_EQ("class_none",300      fir::getTypeAsString(301          fir::ClassType::get(mlir::NoneType::get(&context)), *kindMap));302  auto derivedTy = fir::RecordType::get(&context, "derived");303  llvm::SmallVector<std::pair<std::string, mlir::Type>> components;304  components.emplace_back("p1", mlir::IntegerType::get(&context, 64));305  derivedTy.finalize({}, components);306  EXPECT_EQ("rec_derived", fir::getTypeAsString(derivedTy, *kindMap));307  mlir::Type dynArrTy =308      fir::SequenceType::get({fir::SequenceType::getUnknownExtent(),309                                 fir::SequenceType::getUnknownExtent()},310          ty);311  EXPECT_EQ("UxUxi64", fir::getTypeAsString(dynArrTy, *kindMap));312  EXPECT_EQ("llvmptr_i32",313      fir::getTypeAsString(314          fir::LLVMPointerType::get(mlir::IntegerType::get(&context, 32)),315          *kindMap));316  EXPECT_EQ("boxchar_c8xU",317      fir::getTypeAsString(fir::BoxCharType::get(&context, 1), *kindMap));318}319 320TEST_F(FIRTypesTest, isVolatileType) {321  mlir::Type i32 = mlir::IntegerType::get(&context, 32);322 323  mlir::Type i32NonVolatileRef = fir::ReferenceType::get(i32);324  mlir::Type i32NonVolatileBox = fir::BoxType::get(i32);325  mlir::Type i32NonVolatileClass = fir::ClassType::get(i32);326 327  // Ensure the default value is false328  EXPECT_EQ(i32NonVolatileRef, fir::ReferenceType::get(i32, false));329  EXPECT_EQ(i32NonVolatileBox, fir::BoxType::get(i32, false));330  EXPECT_EQ(i32NonVolatileClass, fir::ClassType::get(i32, false));331 332  EXPECT_FALSE(fir::isa_volatile_type(i32));333  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileRef));334  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileBox));335  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileClass));336 337  // Should return the same type if it's not capable of representing volatility.338  EXPECT_EQ(i32, fir::updateTypeWithVolatility(i32, true));339 340  mlir::Type i32VolatileRef =341      fir::updateTypeWithVolatility(i32NonVolatileRef, true);342  mlir::Type i32VolatileBox =343      fir::updateTypeWithVolatility(i32NonVolatileBox, true);344  mlir::Type i32VolatileClass =345      fir::updateTypeWithVolatility(i32NonVolatileClass, true);346 347  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileRef));348  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileBox));349  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileClass));350 351  EXPECT_EQ(i32VolatileRef, fir::ReferenceType::get(i32, true));352  EXPECT_EQ(i32VolatileBox, fir::BoxType::get(i32, true));353  EXPECT_EQ(i32VolatileClass, fir::ClassType::get(i32, true));354}355