9
9
#include " PassDetail.h"
10
10
#include " flang/Lower/Todo.h" // delete!
11
11
#include " flang/Optimizer/Builder/BoxValue.h"
12
+ #include " flang/Optimizer/Builder/Character.h"
12
13
#include " flang/Optimizer/Builder/FIRBuilder.h"
13
14
#include " flang/Optimizer/Builder/Factory.h"
14
15
#include " flang/Optimizer/Dialect/FIRDialect.h"
@@ -240,7 +241,7 @@ class ReachCollector {
240
241
return ;
241
242
}
242
243
243
- fir:: emitFatalError (val.getLoc (), " unhandled value" );
244
+ emitFatalError (val.getLoc (), " unhandled value" );
244
245
}
245
246
246
247
// / Return all ops that produce the array value that is stored into the
@@ -249,8 +250,7 @@ class ReachCollector {
249
250
mlir::Value seq) {
250
251
reach.clear ();
251
252
mlir::Region *loopRegion = nullptr ;
252
- if (auto doLoop =
253
- mlir::dyn_cast_or_null<fir::DoLoopOp>(seq.getDefiningOp ()))
253
+ if (auto doLoop = mlir::dyn_cast_or_null<DoLoopOp>(seq.getDefiningOp ()))
254
254
loopRegion = &doLoop->getRegion (0 );
255
255
ReachCollector collector (reach, loopRegion);
256
256
collector.collectArrayMentionFrom (seq);
@@ -392,11 +392,11 @@ static bool conflictOnLoad(llvm::ArrayRef<mlir::Operation *> reach,
392
392
ArrayMergeStoreOp st) {
393
393
mlir::Value load;
394
394
auto addr = st.memref ();
395
- auto stEleTy = fir:: dyn_cast_ptrOrBoxEleTy (addr.getType ());
395
+ auto stEleTy = dyn_cast_ptrOrBoxEleTy (addr.getType ());
396
396
for (auto *op : reach)
397
397
if (auto ld = mlir::dyn_cast<ArrayLoadOp>(op)) {
398
398
auto ldTy = ld.memref ().getType ();
399
- if (auto boxTy = ldTy.dyn_cast <fir:: BoxType>())
399
+ if (auto boxTy = ldTy.dyn_cast <BoxType>())
400
400
ldTy = boxTy.getEleTy ();
401
401
if (ldTy.isa <fir::PointerType>() && stEleTy == dyn_cast_ptrEleTy (ldTy))
402
402
return true ;
@@ -597,12 +597,12 @@ static mlir::Type getEleTy(mlir::Type ty) {
597
597
static void getExtents (llvm::SmallVectorImpl<mlir::Value> &result,
598
598
mlir::Value shape) {
599
599
auto *shapeOp = shape.getDefiningOp ();
600
- if (auto s = mlir::dyn_cast<fir:: ShapeOp>(shapeOp)) {
600
+ if (auto s = mlir::dyn_cast<ShapeOp>(shapeOp)) {
601
601
auto e = s.getExtents ();
602
602
result.insert (result.end (), e.begin (), e.end ());
603
603
return ;
604
604
}
605
- if (auto s = mlir::dyn_cast<fir:: ShapeShiftOp>(shapeOp)) {
605
+ if (auto s = mlir::dyn_cast<ShapeShiftOp>(shapeOp)) {
606
606
auto e = s.getExtents ();
607
607
result.insert (result.end (), e.begin (), e.end ());
608
608
return ;
@@ -619,31 +619,30 @@ static void getExtents(llvm::SmallVectorImpl<mlir::Value> &result,
619
619
// argument of the ArrayLoadOp that is returned.
620
620
static mlir::Value
621
621
getOrReadExtentsAndShapeOp (mlir::Location loc, mlir::PatternRewriter &rewriter,
622
- fir:: ArrayLoadOp loadOp,
622
+ ArrayLoadOp loadOp,
623
623
llvm::SmallVectorImpl<mlir::Value> &result) {
624
624
assert (result.empty ());
625
- if (auto boxTy = loadOp.memref ().getType ().dyn_cast <fir::BoxType>()) {
626
- auto rank = fir::dyn_cast_ptrOrBoxEleTy (boxTy)
627
- .cast <fir::SequenceType>()
628
- .getDimension ();
625
+ if (auto boxTy = loadOp.memref ().getType ().dyn_cast <BoxType>()) {
626
+ auto rank =
627
+ dyn_cast_ptrOrBoxEleTy (boxTy).cast <SequenceType>().getDimension ();
629
628
auto idxTy = rewriter.getIndexType ();
630
629
for (decltype (rank) dim = 0 ; dim < rank; ++dim) {
631
630
auto dimVal = rewriter.create <mlir::ConstantIndexOp>(loc, dim);
632
- auto dimInfo = rewriter.create <fir:: BoxDimsOp>(loc, idxTy, idxTy, idxTy,
633
- loadOp.memref (), dimVal);
631
+ auto dimInfo = rewriter.create <BoxDimsOp>(loc, idxTy, idxTy, idxTy,
632
+ loadOp.memref (), dimVal);
634
633
result.emplace_back (dimInfo.getResult (1 ));
635
634
}
636
- auto shapeType = fir:: ShapeType::get (rewriter.getContext (), rank);
637
- return rewriter.create <fir:: ShapeOp>(loc, shapeType, result);
635
+ auto shapeType = ShapeType::get (rewriter.getContext (), rank);
636
+ return rewriter.create <ShapeOp>(loc, shapeType, result);
638
637
}
639
638
getExtents (result, loadOp.shape ());
640
639
return loadOp.shape ();
641
640
}
642
641
643
642
static mlir::Type toRefType (mlir::Type ty) {
644
- if (fir:: isa_ref_type (ty))
643
+ if (isa_ref_type (ty))
645
644
return ty;
646
- return fir:: ReferenceType::get (ty);
645
+ return ReferenceType::get (ty);
647
646
}
648
647
649
648
static mlir::Value
@@ -655,55 +654,73 @@ genCoorOp(mlir::PatternRewriter &rewriter, mlir::Location loc, mlir::Type eleTy,
655
654
if (skipOrig)
656
655
originated.assign (indices.begin (), indices.end ());
657
656
else
658
- originated = fir:: factory::originateIndices (loc, rewriter, alloc.getType (),
659
- shape, indices);
660
- auto seqTy = fir:: dyn_cast_ptrOrBoxEleTy (alloc.getType ());
661
- assert (seqTy && seqTy.isa <fir:: SequenceType>());
662
- const auto dimension = seqTy.cast <fir:: SequenceType>().getDimension ();
663
- mlir::Value result = rewriter.create <fir:: ArrayCoorOp>(
657
+ originated = factory::originateIndices (loc, rewriter, alloc.getType (),
658
+ shape, indices);
659
+ auto seqTy = dyn_cast_ptrOrBoxEleTy (alloc.getType ());
660
+ assert (seqTy && seqTy.isa <SequenceType>());
661
+ const auto dimension = seqTy.cast <SequenceType>().getDimension ();
662
+ mlir::Value result = rewriter.create <ArrayCoorOp>(
664
663
loc, eleTy, alloc, shape, slice,
665
664
llvm::ArrayRef<mlir::Value>{originated}.take_front (dimension),
666
665
typeparams);
667
666
if (dimension < originated.size ())
668
- result = rewriter.create <fir:: CoordinateOp>(
667
+ result = rewriter.create <CoordinateOp>(
669
668
loc, resTy, result,
670
669
llvm::ArrayRef<mlir::Value>{originated}.drop_front (dimension));
671
670
return result;
672
671
}
673
672
673
+ // / Generate an array copy. This is used for both copy-in and copy-out.
674
674
static void genArrayCopy (mlir::Location loc, mlir::PatternRewriter &rewriter,
675
675
mlir::Value dst, mlir::Value src, mlir::Value shapeOp,
676
- mlir::Type arrTy) {
676
+ ArrayLoadOp arrLoad) {
677
+ auto arrTy = arrLoad.getType ();
677
678
auto insPt = rewriter.saveInsertionPoint ();
678
679
llvm::SmallVector<mlir::Value> indices;
679
680
llvm::SmallVector<mlir::Value> extents;
680
681
getExtents (extents, shapeOp);
681
682
// Build loop nest from column to row.
682
683
for (auto sh : llvm::reverse (extents)) {
683
684
auto idxTy = rewriter.getIndexType ();
684
- auto ubi = rewriter.create <fir:: ConvertOp>(loc, idxTy, sh);
685
+ auto ubi = rewriter.create <ConvertOp>(loc, idxTy, sh);
685
686
auto zero = rewriter.create <mlir::ConstantIndexOp>(loc, 0 );
686
687
auto one = rewriter.create <mlir::ConstantIndexOp>(loc, 1 );
687
688
auto ub = rewriter.create <mlir::SubIOp>(loc, idxTy, ubi, one);
688
- auto loop = rewriter.create <fir:: DoLoopOp>(loc, zero, ub, one);
689
+ auto loop = rewriter.create <DoLoopOp>(loc, zero, ub, one);
689
690
rewriter.setInsertionPointToStart (loop.getBody ());
690
691
indices.push_back (loop.getInductionVar ());
691
692
}
692
693
// Reverse the indices so they are in column-major order.
693
694
std::reverse (indices.begin (), indices.end ());
694
695
auto ty = getEleTy (arrTy);
695
- auto fromAddr = rewriter.create <fir::ArrayCoorOp>(
696
+ auto typeparams = arrLoad.typeparams ();
697
+ auto fromAddr = rewriter.create <ArrayCoorOp>(
696
698
loc, ty, src, shapeOp, mlir::Value{},
697
- fir::factory::originateIndices (loc, rewriter, src.getType (), shapeOp,
698
- indices),
699
- mlir::ValueRange{});
700
- auto load = rewriter.create <fir::LoadOp>(loc, fromAddr);
701
- auto toAddr = rewriter.create <fir::ArrayCoorOp>(
699
+ factory::originateIndices (loc, rewriter, src.getType (), shapeOp, indices),
700
+ typeparams);
701
+ auto toAddr = rewriter.create <ArrayCoorOp>(
702
702
loc, ty, dst, shapeOp, mlir::Value{},
703
- fir::factory::originateIndices (loc, rewriter, dst.getType (), shapeOp,
704
- indices),
705
- mlir::ValueRange{});
706
- rewriter.create <fir::StoreOp>(loc, load, toAddr);
703
+ factory::originateIndices (loc, rewriter, dst.getType (), shapeOp, indices),
704
+ typeparams);
705
+ auto eleTy = unwrapSequenceType (unwrapRefType (arrTy));
706
+ if (hasDynamicSize (eleTy)) {
707
+ if (auto charTy = eleTy.dyn_cast <fir::CharacterType>()) {
708
+ assert (charTy.hasDynamicLen () && " dynamic size and constant length" );
709
+ // Copy from (to) object to (from) temp copy of same object.
710
+ auto len = typeparams.back ();
711
+ CharBoxValue toChar (toAddr, len);
712
+ CharBoxValue fromChar (fromAddr, len);
713
+ auto module = toAddr->getParentOfType <mlir::ModuleOp>();
714
+ FirOpBuilder builder{rewriter, getKindMapping (module )};
715
+ factory::CharacterExprHelper helper{builder, loc};
716
+ helper.createAssign (ExtendedValue{toChar}, ExtendedValue{fromChar});
717
+ } else {
718
+ TODO (loc, " copy element of dynamic size" );
719
+ }
720
+ } else {
721
+ auto load = rewriter.create <fir::LoadOp>(loc, fromAddr);
722
+ rewriter.create <fir::StoreOp>(loc, load, toAddr);
723
+ }
707
724
rewriter.restoreInsertionPoint (insPt);
708
725
}
709
726
@@ -740,20 +757,20 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
740
757
loc, dyn_cast_ptrOrBoxEleTy (load.memref ().getType ()), load.typeparams (),
741
758
extents);
742
759
genArrayCopy (load.getLoc (), rewriter, allocmem, load.memref (), shapeOp,
743
- load. getType () );
760
+ load);
744
761
// Generate the reference for the access.
745
762
rewriter.setInsertionPoint (op);
746
763
auto coor =
747
764
genCoorOp (rewriter, loc, getEleTy (load.getType ()), eleTy, allocmem,
748
765
shapeOp, load.slice (), access.indices (), load.typeparams (),
749
- access->hasAttr (fir:: factory::attrFortranArrayOffsets ()));
766
+ access->hasAttr (factory::attrFortranArrayOffsets ()));
750
767
// Copy out.
751
768
auto *storeOp = useMap.lookup (loadOp);
752
769
auto store = mlir::cast<ArrayMergeStoreOp>(storeOp);
753
770
rewriter.setInsertionPoint (storeOp);
754
771
// Copy out.
755
772
genArrayCopy (store.getLoc (), rewriter, store.memref (), allocmem, shapeOp,
756
- load. getType () );
773
+ load);
757
774
rewriter.create <FreeMemOp>(loc, allocmem);
758
775
return coor;
759
776
}
@@ -786,19 +803,19 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
786
803
loc, dyn_cast_ptrOrBoxEleTy (load.memref ().getType ()),
787
804
load.typeparams (), extents);
788
805
genArrayCopy (load.getLoc (), rewriter, allocmem, load.memref (), shapeOp,
789
- load. getType () );
806
+ load);
790
807
rewriter.setInsertionPoint (op);
791
808
auto coor = genCoorOp (
792
809
rewriter, loc, getEleTy (load.getType ()), lhsEltRefType, allocmem,
793
810
shapeOp, load.slice (), update.indices (), load.typeparams (),
794
- update->hasAttr (fir:: factory::attrFortranArrayOffsets ()));
811
+ update->hasAttr (factory::attrFortranArrayOffsets ()));
795
812
assignElement (coor);
796
813
auto *storeOp = useMap.lookup (loadOp);
797
814
auto store = mlir::cast<ArrayMergeStoreOp>(storeOp);
798
815
rewriter.setInsertionPoint (storeOp);
799
816
// Copy out.
800
817
genArrayCopy (store.getLoc (), rewriter, store.memref (), allocmem, shapeOp,
801
- load. getType () );
818
+ load);
802
819
rewriter.create <FreeMemOp>(loc, allocmem);
803
820
return {coor, load.getResult ()};
804
821
}
@@ -807,10 +824,10 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
807
824
LLVM_DEBUG (llvm::outs () << " No, conflict wasn't found\n " );
808
825
rewriter.setInsertionPoint (op);
809
826
auto coorTy = getEleTy (load.getType ());
810
- auto coor = genCoorOp (
811
- rewriter, loc, coorTy, lhsEltRefType, load.memref (), load.shape (),
812
- load. slice (), update. indices (), load.typeparams (),
813
- update->hasAttr (fir:: factory::attrFortranArrayOffsets ()));
827
+ auto coor = genCoorOp (rewriter, loc, coorTy, lhsEltRefType, load. memref (),
828
+ load.shape (), load.slice (), update. indices (),
829
+ load.typeparams (),
830
+ update->hasAttr (factory::attrFortranArrayOffsets ()));
814
831
assignElement (coor);
815
832
return {coor, load.getResult ()};
816
833
}
@@ -833,8 +850,8 @@ class ArrayUpdateConversion : public ArrayUpdateConversionBase<ArrayUpdateOp> {
833
850
auto loc = update.getLoc ();
834
851
auto assignElement = [&](mlir::Value coor) {
835
852
auto input = update.merge ();
836
- if (auto inEleTy = fir:: dyn_cast_ptrEleTy (input.getType ())) {
837
- fir:: emitFatalError (loc, " array_update on references not supported" );
853
+ if (auto inEleTy = dyn_cast_ptrEleTy (input.getType ())) {
854
+ emitFatalError (loc, " array_update on references not supported" );
838
855
} else {
839
856
rewriter.create <fir::StoreOp>(loc, input, coor);
840
857
}
@@ -884,12 +901,11 @@ class ArrayFetchConversion : public mlir::OpRewritePattern<ArrayFetchOp> {
884
901
rewriter.setInsertionPoint (op);
885
902
auto load = mlir::cast<ArrayLoadOp>(useMap.lookup (op));
886
903
auto loc = fetch.getLoc ();
887
- auto coor =
888
- genCoorOp (rewriter, loc, getEleTy (load.getType ()),
889
- toRefType (fetch.getType ()), load.memref (), load.shape (),
890
- load.slice (), fetch.indices (), load.typeparams (),
891
- fetch->hasAttr (fir::factory::attrFortranArrayOffsets ()));
892
- if (fir::isa_ref_type (fetch.getType ()))
904
+ auto coor = genCoorOp (
905
+ rewriter, loc, getEleTy (load.getType ()), toRefType (fetch.getType ()),
906
+ load.memref (), load.shape (), load.slice (), fetch.indices (),
907
+ load.typeparams (), fetch->hasAttr (factory::attrFortranArrayOffsets ()));
908
+ if (isa_ref_type (fetch.getType ()))
893
909
rewriter.replaceOp (fetch, coor);
894
910
else
895
911
rewriter.replaceOpWithNewOp <fir::LoadOp>(fetch, coor);
@@ -924,11 +940,10 @@ class ArrayAccessConversion : public ArrayUpdateConversionBase<ArrayAccessOp> {
924
940
}
925
941
rewriter.setInsertionPoint (op);
926
942
auto load = mlir::cast<ArrayLoadOp>(useMap.lookup (op));
927
- auto coor =
928
- genCoorOp (rewriter, loc, getEleTy (load.getType ()),
929
- toRefType (access.getType ()), load.memref (), load.shape (),
930
- load.slice (), access.indices (), load.typeparams (),
931
- access->hasAttr (fir::factory::attrFortranArrayOffsets ()));
943
+ auto coor = genCoorOp (
944
+ rewriter, loc, getEleTy (load.getType ()), toRefType (access.getType ()),
945
+ load.memref (), load.shape (), load.slice (), access.indices (),
946
+ load.typeparams (), access->hasAttr (factory::attrFortranArrayOffsets ()));
932
947
rewriter.replaceOp (access, coor);
933
948
return mlir::success ();
934
949
}
@@ -949,7 +964,7 @@ class ArrayAmendConversion : public mlir::OpRewritePattern<ArrayAmendOp> {
949
964
auto *op = amend.getOperation ();
950
965
rewriter.setInsertionPoint (op);
951
966
auto loc = amend.getLoc ();
952
- auto undef = rewriter.create <fir:: UndefOp>(loc, amend.getType ());
967
+ auto undef = rewriter.create <UndefOp>(loc, amend.getType ());
953
968
rewriter.replaceOp (amend, undef.getResult ());
954
969
return mlir::success ();
955
970
}
0 commit comments