clang 24.0.0git
RecordTypeConverter.h
Go to the documentation of this file.
1//===- RecordTypeConverter.h - Record-rebuilding type converter -*- C++ -*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// A type converter base for CIR-to-CIR passes that rewrite types nested in
10// records.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H
15#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H
16
17#include "mlir/Transforms/DialectConversion.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/Support/RWMutex.h"
23
24#include <memory>
25
26namespace cir {
27
28/// A type converter that converts the types nested in pointers, arrays,
29/// functions and records.
30///
31/// Identified records can't be modified in place, so each one is rebuilt under
32/// a temporary name (see RecordType::getABIConvertedName). The conversion keeps
33/// a stack of the records being converted, which resolves recursive records.
34/// Once the conversion is done, restoreRecordTypeNames() gives the rebuilt
35/// records their original names back.
36///
37/// Subclasses add conversions for the types they rewrite. The type converter
38/// tries the most recently added conversion first, so a subclass can also
39/// replace one of the conversions registered here.
40///
41/// Every record is rebuilt unless typeMayChange() is overridden.
42class RecordRewritingTypeConverter : public mlir::TypeConverter {
43public:
44 explicit RecordRewritingTypeConverter(mlir::MLIRContext &context);
45 virtual ~RecordRewritingTypeConverter() = default;
46
47 /// Remove the temporary name of every record rebuilt by this converter.
49
50protected:
51 /// Whether \p type itself, ignoring nested types, may change. Records are
52 /// rebuilt only if some type they reach returns true.
53 virtual bool typeMayChange(mlir::Type type) const { return true; }
54
55private:
56 bool recordNeedsConversion(cir::RecordType type);
57 bool reachesChangingType(mlir::Type type,
58 llvm::SmallPtrSetImpl<mlir::Type> &visiting) const;
59 cir::RecordType convertRecordType(cir::RecordType type);
60 llvm::SmallVector<mlir::Type> convertRecordMemberTypes(cir::RecordType type);
61 llvm::SmallVector<cir::RecordType> &getCurrentThreadRecursiveStack();
62 void addConvertedRecordType(cir::RecordType rt);
63
64 mlir::MLIRContext &context;
65
66 // Recursive structure detection.
67 // We store one entry per thread here, and rely on locking. This works the
68 // same way as the LLVM-IR lowering does it, which has a similar problem.
69 llvm::DenseMap<uint64_t, std::unique_ptr<llvm::SmallVector<cir::RecordType>>>
70 conversionCallStack;
71 llvm::sys::SmartRWMutex<true> callStackMutex;
72
73 // In order to let us 'change the names' back after the fact, we collect them
74 // along the way. They should only be added/accessed via the thread-safe
75 // functions.
76 llvm::SmallVector<cir::RecordType> convertedRecordTypes;
77 llvm::sys::SmartRWMutex<true> recordTypeMutex;
78
79 // Cached results of recordNeedsConversion().
80 llvm::DenseMap<mlir::Type, bool> recordNeedsConversionCache;
81 llvm::sys::SmartRWMutex<true> recordNeedsConversionMutex;
82};
83
84} // namespace cir
85
86#endif // CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H
void restoreRecordTypeNames()
Remove the temporary name of every record rebuilt by this converter.
virtual bool typeMayChange(mlir::Type type) const
Whether type itself, ignoring nested types, may change.
virtual ~RecordRewritingTypeConverter()=default
RecordRewritingTypeConverter(mlir::MLIRContext &context)
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:150