Skip to content

Commit df3f0ee

Browse files
authored
[flang] Fix invalid iterator erasure in boxed-procedure pass (llvm#79830)
The code in BoxedProcedureRewrite was erasing the mappings <old type, new type> once "new type" was fully translated. This was done in an invalid way because the map was an llvm::SmallMapVector that do not have stable iterators, and new items were added to the map between the creation of the iterator and its erasure. It is anyway not needed and expensive to erase the types (see llvm::MapVector note), the cache can be used for the whole pass, which is very beneficial in the context of an apps using "big derived types" (dozens of components/parents).
1 parent ce72f78 commit df3f0ee

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "mlir/IR/PatternMatch.h"
2020
#include "mlir/Pass/Pass.h"
2121
#include "mlir/Transforms/DialectConversion.h"
22-
#include "llvm/ADT/MapVector.h"
22+
#include "llvm/ADT/DenseMap.h"
2323

2424
namespace fir {
2525
#define GEN_PASS_DEF_BOXEDPROCEDUREPASS
@@ -133,13 +133,16 @@ class BoxprocTypeRewriter : public mlir::TypeConverter {
133133
addConversion([&](RecordType ty) -> mlir::Type {
134134
if (!needsConversion(ty))
135135
return ty;
136-
if (auto converted = typeInConversion.lookup(ty))
136+
if (auto converted = convertedTypes.lookup(ty))
137137
return converted;
138138
auto rec = RecordType::get(ty.getContext(),
139139
ty.getName().str() + boxprocSuffix.str());
140140
if (rec.isFinalized())
141141
return rec;
142-
auto it = typeInConversion.try_emplace(ty, rec);
142+
auto it = convertedTypes.try_emplace(ty, rec);
143+
if (!it.second) {
144+
llvm::errs() << "failed\n" << ty << "\n";
145+
}
143146
std::vector<RecordType::TypePair> ps = ty.getLenParamList();
144147
std::vector<RecordType::TypePair> cs;
145148
for (auto t : ty.getTypeList()) {
@@ -149,7 +152,6 @@ class BoxprocTypeRewriter : public mlir::TypeConverter {
149152
cs.emplace_back(t.first, t.second);
150153
}
151154
rec.finalize(ps, cs);
152-
typeInConversion.erase(it.first);
153155
return rec;
154156
});
155157
addArgumentMaterialization(materializeProcedure);
@@ -170,7 +172,11 @@ class BoxprocTypeRewriter : public mlir::TypeConverter {
170172

171173
private:
172174
llvm::SmallVector<mlir::Type> visitedTypes;
173-
llvm::SmallMapVector<mlir::Type, mlir::Type, 8> typeInConversion;
175+
// Map to deal with recursive derived types (avoid infinite loops).
176+
// Caching is also beneficial for apps with big types (dozens of
177+
// components and or parent types), so the lifetime of the cache
178+
// is the whole pass.
179+
llvm::DenseMap<mlir::Type, mlir::Type> convertedTypes;
174180
mlir::Location loc;
175181
};
176182

flang/test/Fir/boxproc-2.fir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,9 @@ func.func @box_addr_test(%arg0: !fir.box<!t2>) -> !fir.ref<!t2> {
102102
}
103103
// CHECK: func.func @box_addr_test(
104104
// CHECK: fir.box_addr %{{.*}} : (!fir.box<!fir.type<t2UnboxProc{i:() -> ()}>>) -> !fir.ref<!fir.type<t2UnboxProc{i:() -> ()}>>
105+
106+
func.func @very_nested_type(%arg0: !fir.type<t0{t01:!fir.type<t01{t02:!fir.type<t02{t3:!fir.type<t3{t4:!fir.type<t4{t5:!fir.type<t5{t6:!fir.type<t6{t7:!fir.type<t7{t8:!fir.type<t8{t9:!fir.type<t9{t10:!fir.type<t10{t11:!fir.type<t11{t12:!fir.type<t12{t13:!fir.type<t13{t14:!fir.type<t14{t15:!fir.type<t15{t16:!fir.type<t16{t17:!fir.type<t17{t18:!fir.type<t18{t19:!fir.type<t19{b:!fir.boxproc<()->()>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>) {
107+
return
108+
}
109+
// CHECK-LABEL: func.func @very_nested_type(
110+
// CHECK-SAME: !fir.type<t0UnboxProc{t01:!fir.type<t01UnboxProc{t02:!fir.type<t02UnboxProc{t3:!fir.type<t3UnboxProc{t4:!fir.type<t4UnboxProc{t5:!fir.type<t5UnboxProc{t6:!fir.type<t6UnboxProc{t7:!fir.type<t7UnboxProc{t8:!fir.type<t8UnboxProc{t9:!fir.type<t9UnboxProc{t10:!fir.type<t10UnboxProc{t11:!fir.type<t11UnboxProc{t12:!fir.type<t12UnboxProc{t13:!fir.type<t13UnboxProc{t14:!fir.type<t14UnboxProc{t15:!fir.type<t15UnboxProc{t16:!fir.type<t16UnboxProc{t17:!fir.type<t17UnboxProc{t18:!fir.type<t18UnboxProc{t19:!fir.type<t19UnboxProc{b:() -> ()}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>}>)

0 commit comments

Comments
 (0)