7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " flang/Optimizer/Builder/FIRBuilder.h"
10
+ #include " flang/Optimizer/Dialect/FIROpsSupport.h"
11
+ #include " flang/Optimizer/Support/FatalError.h"
12
+ #include " flang/Optimizer/Support/InternalNames.h"
13
+ #include " llvm/ADT/StringExtras.h"
14
+ #include " llvm/Support/CommandLine.h"
15
+ #include " llvm/Support/MD5.h"
16
+
17
+ static llvm::cl::opt<std::size_t >
18
+ nameLengthHashSize (" length-to-hash-string-literal" ,
19
+ llvm::cl::desc (" string literals that exceed this length"
20
+ " will use a hash value as their symbol "
21
+ " name" ),
22
+ llvm::cl::init(32 ));
23
+
24
+ mlir::FuncOp fir::FirOpBuilder::createFunction (mlir::Location loc,
25
+ mlir::ModuleOp module,
26
+ llvm::StringRef name,
27
+ mlir::FunctionType ty) {
28
+ return fir::createFuncOp (loc, module, name, ty);
29
+ }
30
+
31
+ mlir::FuncOp fir::FirOpBuilder::getNamedFunction (mlir::ModuleOp modOp,
32
+ llvm::StringRef name) {
33
+ return modOp.lookupSymbol <mlir::FuncOp>(name);
34
+ }
35
+
36
+ fir::GlobalOp fir::FirOpBuilder::getNamedGlobal (mlir::ModuleOp modOp,
37
+ llvm::StringRef name) {
38
+ return modOp.lookupSymbol <fir::GlobalOp>(name);
39
+ }
40
+
41
+ mlir::Type fir::FirOpBuilder::getRefType (mlir::Type eleTy) {
42
+ assert (!eleTy.isa <fir::ReferenceType>() && " cannot be a reference type" );
43
+ return fir::ReferenceType::get (eleTy);
44
+ }
45
+
46
+ mlir::Type fir::FirOpBuilder::getVarLenSeqTy (mlir::Type eleTy, unsigned rank) {
47
+ fir::SequenceType::Shape shape (rank, fir::SequenceType::getUnknownExtent ());
48
+ return fir::SequenceType::get (shape, eleTy);
49
+ }
50
+
51
+ mlir::Type fir::FirOpBuilder::getRealType (int kind) {
52
+ switch (kindMap.getRealTypeID (kind)) {
53
+ case llvm::Type::TypeID::HalfTyID:
54
+ return mlir::FloatType::getF16 (getContext ());
55
+ case llvm::Type::TypeID::FloatTyID:
56
+ return mlir::FloatType::getF32 (getContext ());
57
+ case llvm::Type::TypeID::DoubleTyID:
58
+ return mlir::FloatType::getF64 (getContext ());
59
+ case llvm::Type::TypeID::X86_FP80TyID:
60
+ return mlir::FloatType::getF80 (getContext ());
61
+ case llvm::Type::TypeID::FP128TyID:
62
+ return mlir::FloatType::getF128 (getContext ());
63
+ default :
64
+ fir::emitFatalError (UnknownLoc::get (getContext ()),
65
+ " unsupported type !fir.real<kind>" );
66
+ }
67
+ }
68
+
69
+ mlir::Value fir::FirOpBuilder::createNullConstant (mlir::Location loc,
70
+ mlir::Type ptrType) {
71
+ auto ty = ptrType ? ptrType : getRefType (getNoneType ());
72
+ return create<fir::ZeroOp>(loc, ty);
73
+ }
10
74
11
75
mlir::Value fir::FirOpBuilder::createIntegerConstant (mlir::Location loc,
12
76
mlir::Type ty,
13
77
std::int64_t cst) {
14
78
return create<mlir::ConstantOp>(loc, ty, getIntegerAttr (ty, cst));
15
79
}
16
80
81
+ mlir::Value
82
+ fir::FirOpBuilder::createRealConstant (mlir::Location loc, mlir::Type fltTy,
83
+ llvm::APFloat::integerPart val) {
84
+ auto apf = [&]() -> llvm::APFloat {
85
+ if (auto ty = fltTy.dyn_cast <fir::RealType>())
86
+ return llvm::APFloat (kindMap.getFloatSemantics (ty.getFKind ()), val);
87
+ if (fltTy.isF16 ())
88
+ return llvm::APFloat (llvm::APFloat::IEEEhalf (), val);
89
+ if (fltTy.isBF16 ())
90
+ return llvm::APFloat (llvm::APFloat::BFloat (), val);
91
+ if (fltTy.isF32 ())
92
+ return llvm::APFloat (llvm::APFloat::IEEEsingle (), val);
93
+ if (fltTy.isF64 ())
94
+ return llvm::APFloat (llvm::APFloat::IEEEdouble (), val);
95
+ if (fltTy.isF80 ())
96
+ return llvm::APFloat (llvm::APFloat::x87DoubleExtended (), val);
97
+ if (fltTy.isF128 ())
98
+ return llvm::APFloat (llvm::APFloat::IEEEquad (), val);
99
+ llvm_unreachable (" unhandled MLIR floating-point type" );
100
+ };
101
+ return createRealConstant (loc, fltTy, apf ());
102
+ }
103
+
104
+ mlir::Value fir::FirOpBuilder::createRealConstant (mlir::Location loc,
105
+ mlir::Type fltTy,
106
+ const llvm::APFloat &value) {
107
+ if (fltTy.isa <mlir::FloatType>()) {
108
+ auto attr = getFloatAttr (fltTy, value);
109
+ return create<mlir::arith::ConstantOp>(loc, fltTy, attr);
110
+ }
111
+ llvm_unreachable (" should use builtin floating-point type" );
112
+ }
113
+
114
+ // / Create a global variable in the (read-only) data section. A global variable
115
+ // / must have a unique name to identify and reference it.
116
+ fir::GlobalOp
117
+ fir::FirOpBuilder::createGlobal (mlir::Location loc, mlir::Type type,
118
+ llvm::StringRef name, mlir::StringAttr linkage,
119
+ mlir::Attribute value, bool isConst) {
120
+ auto module = getModule ();
121
+ auto insertPt = saveInsertionPoint ();
122
+ if (auto glob = module.lookupSymbol <fir::GlobalOp>(name))
123
+ return glob;
124
+ setInsertionPoint (module.getBody (), module.getBody ()->end ());
125
+ auto glob = create<fir::GlobalOp>(loc, name, isConst, type, value, linkage);
126
+ restoreInsertionPoint (insertPt);
127
+ return glob;
128
+ }
129
+
130
+ fir::GlobalOp fir::FirOpBuilder::createGlobal (
131
+ mlir::Location loc, mlir::Type type, llvm::StringRef name, bool isConst,
132
+ std::function<void (FirOpBuilder &)> bodyBuilder, mlir::StringAttr linkage) {
133
+ auto module = getModule ();
134
+ auto insertPt = saveInsertionPoint ();
135
+ if (auto glob = module.lookupSymbol <fir::GlobalOp>(name))
136
+ return glob;
137
+ setInsertionPoint (module.getBody (), module.getBody ()->end ());
138
+ auto glob = create<fir::GlobalOp>(loc, name, isConst, type, mlir::Attribute{},
139
+ linkage);
140
+ auto ®ion = glob.getRegion ();
141
+ region.push_back (new mlir::Block);
142
+ auto &block = glob.getRegion ().back ();
143
+ setInsertionPointToStart (&block);
144
+ bodyBuilder (*this );
145
+ restoreInsertionPoint (insertPt);
146
+ return glob;
147
+ }
148
+
17
149
mlir::Value fir::FirOpBuilder::createConvert (mlir::Location loc,
18
150
mlir::Type toTy, mlir::Value val) {
19
151
if (val.getType () != toTy) {
@@ -23,6 +155,19 @@ mlir::Value fir::FirOpBuilder::createConvert(mlir::Location loc,
23
155
return val;
24
156
}
25
157
158
+ fir::StringLitOp fir::FirOpBuilder::createStringLitOp (mlir::Location loc,
159
+ llvm::StringRef data) {
160
+ auto type = fir::CharacterType::get (getContext (), 1 , data.size ());
161
+ auto strAttr = mlir::StringAttr::get (getContext (), data);
162
+ auto valTag = mlir::Identifier::get (fir::StringLitOp::value (), getContext ());
163
+ mlir::NamedAttribute dataAttr (valTag, strAttr);
164
+ auto sizeTag = mlir::Identifier::get (fir::StringLitOp::size (), getContext ());
165
+ mlir::NamedAttribute sizeAttr (sizeTag, getI64IntegerAttr (data.size ()));
166
+ llvm::SmallVector<mlir::NamedAttribute> attrs{dataAttr, sizeAttr};
167
+ return create<fir::StringLitOp>(loc, llvm::ArrayRef<mlir::Type>{type},
168
+ llvm::None, attrs);
169
+ }
170
+
26
171
static mlir::Value genNullPointerComparison (fir::FirOpBuilder &builder,
27
172
mlir::Location loc,
28
173
mlir::Value addr,
@@ -41,3 +186,31 @@ mlir::Value fir::FirOpBuilder::genIsNotNull(mlir::Location loc,
41
186
mlir::Value fir::FirOpBuilder::genIsNull (mlir::Location loc, mlir::Value addr) {
42
187
return genNullPointerComparison (*this , loc, addr, arith::CmpIPredicate::eq);
43
188
}
189
+
190
+ std::string fir::factory::uniqueCGIdent (llvm::StringRef prefix,
191
+ llvm::StringRef name) {
192
+ // For "long" identifiers use a hash value
193
+ if (name.size () > nameLengthHashSize) {
194
+ llvm::MD5 hash;
195
+ hash.update (name);
196
+ llvm::MD5::MD5Result result;
197
+ hash.final (result);
198
+ llvm::SmallString<32 > str;
199
+ llvm::MD5::stringifyResult (result, str);
200
+ std::string hashName = prefix.str ();
201
+ hashName.append (" ." ).append (str.c_str ());
202
+ return fir::NameUniquer::doGenerated (hashName);
203
+ }
204
+ // "Short" identifiers use a reversible hex string
205
+ std::string nm = prefix.str ();
206
+ return fir::NameUniquer::doGenerated (
207
+ nm.append (" ." ).append (llvm::toHex (name)));
208
+ }
209
+
210
+ mlir::Value fir::factory::locationToLineNo (fir::FirOpBuilder &builder,
211
+ mlir::Location loc,
212
+ mlir::Type type) {
213
+ if (auto flc = loc.dyn_cast <mlir::FileLineColLoc>())
214
+ return builder.createIntegerConstant (loc, type, flc.getLine ());
215
+ return builder.createIntegerConstant (loc, type, 0 );
216
+ }
0 commit comments