Skip to content

Commit 0def9a9

Browse files
authored
[flang] Add allocator_idx attribute on fir.embox and fircg.ext_embox (#101212)
#100690 introduces allocator registry with the ability to store allocator index in the descriptor. This patch adds an attribute to fir.embox and fircg.ext_embox to be able to set the allocator index while populating the descriptor fields.
1 parent 160fb11 commit 0def9a9

File tree

8 files changed

+66
-14
lines changed

8 files changed

+66
-14
lines changed

flang/include/flang/Optimizer/CodeGen/CGOps.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def fircg_XEmboxOp : fircg_Op<"ext_embox", [AttrSizedOperandSegments]> {
4848
- substring: A substring operator (offset, length) for CHARACTER.
4949
- LEN type parameters: A vector of runtime LEN type parameters that
5050
describe an correspond to the elemental derived type.
51+
- allocator_idx: specify special allocator to use.
5152

5253
The memref and shape arguments are mandatory. The rest are optional.
5354
}];
@@ -60,7 +61,8 @@ def fircg_XEmboxOp : fircg_Op<"ext_embox", [AttrSizedOperandSegments]> {
6061
Variadic<AnyCoordinateType>:$subcomponent,
6162
Variadic<AnyIntegerType>:$substr,
6263
Variadic<AnyIntegerType>:$lenParams,
63-
Optional<fir_ClassType>:$sourceBox
64+
Optional<fir_ClassType>:$sourceBox,
65+
OptionalAttr<I32Attr>:$allocator_idx
6466
);
6567
let results = (outs BoxOrClassType);
6668

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
783783
- slice: an array section can be described with a slice triple,
784784
- typeparams: for emboxing a derived type with LEN type parameters,
785785
- accessMap: unused/experimental.
786+
- allocator_idx: specify special allocator to use.
786787
}];
787788

788789
let arguments = (ins
@@ -791,7 +792,8 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
791792
Optional<fir_SliceType>:$slice,
792793
Variadic<AnyIntegerType>:$typeparams,
793794
Optional<fir_ClassType>:$sourceBox,
794-
OptionalAttr<AffineMapAttr>:$accessMap
795+
OptionalAttr<AffineMapAttr>:$accessMap,
796+
OptionalAttr<I32Attr>:$allocator_idx
795797
);
796798

797799
let results = (outs BoxOrClassType);
@@ -801,9 +803,11 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
801803
"mlir::Value":$memref, CArg<"mlir::Value", "{}">:$shape,
802804
CArg<"mlir::Value", "{}">:$slice,
803805
CArg<"mlir::ValueRange", "{}">:$typeparams,
804-
CArg<"mlir::Value", "{}">:$sourceBox),
806+
CArg<"mlir::Value", "{}">:$sourceBox,
807+
CArg<"mlir::IntegerAttr", "{}">:$allocator_idx),
805808
[{ return build($_builder, $_state, resultTypes, memref, shape, slice,
806-
typeparams, sourceBox, mlir::AffineMapAttr{}); }]>
809+
typeparams, sourceBox, mlir::AffineMapAttr{},
810+
allocator_idx); }]>
807811
];
808812

809813
let assemblyFormat = [{

flang/runtime/allocator-registry.h renamed to flang/include/flang/Runtime/allocator-registry.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <cstdlib>
1414
#include <vector>
1515

16+
static constexpr unsigned kDefaultAllocator = 0;
17+
1618
#define MAX_ALLOCATOR 5
1719

1820
namespace Fortran::runtime {
@@ -37,7 +39,9 @@ struct AllocatorRegistry {
3739
RT_API_ATTRS constexpr AllocatorRegistry()
3840
: allocators{{&MallocWrapper, &FreeWrapper}} {}
3941
#else
40-
constexpr AllocatorRegistry() { allocators[0] = {&std::malloc, &std::free}; };
42+
constexpr AllocatorRegistry() {
43+
allocators[kDefaultAllocator] = {&std::malloc, &std::free};
44+
};
4145
#endif
4246
RT_API_ATTRS void Register(int, Allocator_t);
4347
RT_API_ATTRS AllocFct GetAllocator(int pos);

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "flang/Optimizer/Support/InternalNames.h"
2424
#include "flang/Optimizer/Support/TypeCode.h"
2525
#include "flang/Optimizer/Support/Utils.h"
26+
#include "flang/Runtime/allocator-registry.h"
27+
#include "flang/Runtime/descriptor.h"
2628
#include "flang/Semantics/runtime-type-info.h"
2729
#include "mlir/Conversion/ArithCommon/AttrToLLVMConverter.h"
2830
#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
@@ -1224,8 +1226,8 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
12241226
fir::BaseBoxType boxTy, mlir::Type inputType,
12251227
mlir::ConversionPatternRewriter &rewriter,
12261228
unsigned rank, mlir::Value eleSize,
1227-
mlir::Value cfiTy,
1228-
mlir::Value typeDesc) const {
1229+
mlir::Value cfiTy, mlir::Value typeDesc,
1230+
int allocatorIdx = kDefaultAllocator) const {
12291231
auto llvmBoxTy = this->lowerTy().convertBoxTypeAsStruct(boxTy, rank);
12301232
bool isUnlimitedPolymorphic = fir::isUnlimitedPolymorphicType(boxTy);
12311233
bool useInputType = fir::isPolymorphicType(boxTy) || isUnlimitedPolymorphic;
@@ -1243,9 +1245,17 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
12431245
this->genI32Constant(loc, rewriter, getCFIAttr(boxTy)));
12441246

12451247
const bool hasAddendum = fir::boxHasAddendum(boxTy);
1248+
1249+
// Descriptor used to set the correct value of the extra field.
1250+
Fortran::runtime::StaticDescriptor<0> staticDescriptor;
1251+
Fortran::runtime::Descriptor &desc{staticDescriptor.descriptor()};
1252+
desc.raw().extra = 0;
1253+
desc.SetAllocIdx(allocatorIdx);
1254+
if (hasAddendum)
1255+
desc.SetHasAddendum();
12461256
descriptor =
12471257
insertField(rewriter, loc, descriptor, {kExtraPosInBox},
1248-
this->genI32Constant(loc, rewriter, hasAddendum ? 1 : 0));
1258+
this->genI32Constant(loc, rewriter, desc.raw().extra));
12491259

12501260
if (hasAddendum) {
12511261
unsigned typeDescFieldId = getTypeDescFieldId(boxTy);
@@ -1300,6 +1310,13 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
13001310
typeparams.push_back(substrParams[1]);
13011311
}
13021312

1313+
int allocatorIdx = 0;
1314+
if constexpr (std::is_same_v<BOX, fir::EmboxOp> ||
1315+
std::is_same_v<BOX, fir::cg::XEmboxOp>) {
1316+
if (box.getAllocatorIdx())
1317+
allocatorIdx = *box.getAllocatorIdx();
1318+
}
1319+
13031320
// Write each of the fields with the appropriate values.
13041321
// When emboxing an element to a polymorphic descriptor, use the
13051322
// input type since the destination descriptor type has not the exact
@@ -1321,8 +1338,9 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
13211338
cfiTy.getType(), rewriter, kTypePosInBox);
13221339
}
13231340
auto mod = box->template getParentOfType<mlir::ModuleOp>();
1324-
mlir::Value descriptor = populateDescriptor(
1325-
loc, mod, boxTy, inputType, rewriter, rank, eleSize, cfiTy, typeDesc);
1341+
mlir::Value descriptor =
1342+
populateDescriptor(loc, mod, boxTy, inputType, rewriter, rank, eleSize,
1343+
cfiTy, typeDesc, allocatorIdx);
13261344

13271345
return {boxTy, descriptor, eleSize};
13281346
}

flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class EmboxConversion : public mlir::OpRewritePattern<fir::EmboxOp> {
109109
auto xbox = rewriter.create<fir::cg::XEmboxOp>(
110110
loc, embox.getType(), embox.getMemref(), shapeOpers, std::nullopt,
111111
std::nullopt, std::nullopt, std::nullopt, embox.getTypeparams(),
112-
embox.getSourceBox());
112+
embox.getSourceBox(), embox.getAllocatorIdxAttr());
113113
LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n');
114114
rewriter.replaceOp(embox, xbox.getOperation()->getResults());
115115
return mlir::success();
@@ -145,7 +145,7 @@ class EmboxConversion : public mlir::OpRewritePattern<fir::EmboxOp> {
145145
auto xbox = rewriter.create<fir::cg::XEmboxOp>(
146146
loc, embox.getType(), embox.getMemref(), shapeOpers, shiftOpers,
147147
sliceOpers, subcompOpers, substrOpers, embox.getTypeparams(),
148-
embox.getSourceBox());
148+
embox.getSourceBox(), embox.getAllocatorIdxAttr());
149149
LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n');
150150
rewriter.replaceOp(embox, xbox.getOperation()->getResults());
151151
return mlir::success();

flang/runtime/allocator-registry.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "allocator-registry.h"
9+
#include "flang/Runtime/allocator-registry.h"
1010
#include "terminator.h"
1111

1212
namespace Fortran::runtime {

flang/runtime/descriptor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88

99
#include "flang/Runtime/descriptor.h"
1010
#include "ISO_Fortran_util.h"
11-
#include "allocator-registry.h"
1211
#include "derived.h"
1312
#include "memory.h"
1413
#include "stat.h"
1514
#include "terminator.h"
1615
#include "tools.h"
1716
#include "type-info.h"
17+
#include "flang/Runtime/allocator-registry.h"
1818
#include <cassert>
1919
#include <cstdlib>
2020
#include <cstring>

flang/test/Fir/embox.fir

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,27 @@ func.func @fir_dev_issue_1416(%arg0: !fir.ref<!fir.array<40x?xf32>>, %low: index
103103
fir.call @do_something(%3) : (!fir.box<!fir.array<?xf32>>) -> ()
104104
return
105105
}
106+
107+
// CHECK-LABEL: define void @_QPtest_allocator1()
108+
func.func @_QPtest_allocator1() {
109+
%c20 = arith.constant 20 : index
110+
%0 = fir.alloca !fir.array<20xi32> {bindc_name = "x", uniq_name = "_QFtest_sliceEx"}
111+
%1 = fir.shape %c20 : (index) -> !fir.shape<1>
112+
%3 = fir.embox %0(%1) {allocator_idx = 1 : i32} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
113+
fir.call @_QPtest_callee(%3) : (!fir.box<!fir.array<?xi32>>) -> ()
114+
return
115+
}
116+
117+
// %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 2, [1 x [3 x i64]] [[3 x i64] [i64 1, i64 20, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64)]] }
118+
119+
// CHECK-LABEL: define void @_QPtest_allocator2()
120+
func.func @_QPtest_allocator2() {
121+
%c20 = arith.constant 20 : index
122+
%0 = fir.alloca !fir.array<20xi32> {bindc_name = "x", uniq_name = "_QFtest_sliceEx"}
123+
%1 = fir.shape %c20 : (index) -> !fir.shape<1>
124+
%3 = fir.embox %0(%1) {allocator_idx = 3 : i32} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
125+
fir.call @_QPtest_callee(%3) : (!fir.box<!fir.array<?xi32>>) -> ()
126+
return
127+
}
128+
129+
// CHECK: %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 6

0 commit comments

Comments
 (0)