@@ -97,6 +97,52 @@ static Type getI1SameShape(Type type) {
97
97
return i1Type;
98
98
}
99
99
100
+ // Parses one of the keywords provided in the list `keywords` and returns the
101
+ // position of the parsed keyword in the list. If none of the keywords from the
102
+ // list is parsed, returns -1.
103
+ static int parseOptionalKeywordAlternative (OpAsmParser &parser,
104
+ ArrayRef<StringRef> keywords) {
105
+ for (const auto &en : llvm::enumerate (keywords)) {
106
+ if (succeeded (parser.parseOptionalKeyword (en.value ())))
107
+ return en.index ();
108
+ }
109
+ return -1 ;
110
+ }
111
+
112
+ namespace {
113
+ template <typename Ty>
114
+ struct EnumTraits {};
115
+
116
+ #define REGISTER_ENUM_TYPE (Ty ) \
117
+ template <> \
118
+ struct EnumTraits <Ty> { \
119
+ static StringRef stringify (Ty value) { return stringify##Ty (value); } \
120
+ static unsigned getMaxEnumVal () { return getMaxEnumValFor##Ty (); } \
121
+ }
122
+
123
+ REGISTER_ENUM_TYPE (Linkage);
124
+ REGISTER_ENUM_TYPE (UnnamedAddr);
125
+ REGISTER_ENUM_TYPE (CConv);
126
+ REGISTER_ENUM_TYPE (Visibility);
127
+ } // namespace
128
+
129
+ // / Parse an enum from the keyword, or default to the provided default value.
130
+ // / The return type is the enum type by default, unless overridden with the
131
+ // / second template argument.
132
+ template <typename EnumTy, typename RetTy = EnumTy>
133
+ static RetTy parseOptionalLLVMKeyword (OpAsmParser &parser,
134
+ OperationState &result,
135
+ EnumTy defaultValue) {
136
+ SmallVector<StringRef, 10 > names;
137
+ for (unsigned i = 0 , e = EnumTraits<EnumTy>::getMaxEnumVal (); i <= e; ++i)
138
+ names.push_back (EnumTraits<EnumTy>::stringify (static_cast <EnumTy>(i)));
139
+
140
+ int index = parseOptionalKeywordAlternative (parser, names);
141
+ if (index == -1 )
142
+ return static_cast <RetTy>(defaultValue);
143
+ return static_cast <RetTy>(index);
144
+ }
145
+
100
146
// ===----------------------------------------------------------------------===//
101
147
// Printing, parsing, folding and builder for LLVM::CmpOp.
102
148
// ===----------------------------------------------------------------------===//
@@ -859,6 +905,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
859
905
build (builder, state, results,
860
906
TypeAttr::get (getLLVMFuncType (builder.getContext (), results, args)),
861
907
callee, args, /* fastmathFlags=*/ nullptr , /* branch_weights=*/ nullptr ,
908
+ /* CConv=*/ nullptr ,
862
909
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
863
910
/* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
864
911
}
@@ -880,7 +927,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
880
927
ValueRange args) {
881
928
build (builder, state, getCallOpResultTypes (calleeType),
882
929
TypeAttr::get (calleeType), callee, args, /* fastmathFlags=*/ nullptr ,
883
- /* branch_weights=*/ nullptr , /* access_groups=*/ nullptr ,
930
+ /* branch_weights=*/ nullptr , /* CConv=*/ nullptr ,
931
+ /* access_groups=*/ nullptr ,
884
932
/* alias_scopes=*/ nullptr , /* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
885
933
}
886
934
@@ -889,6 +937,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
889
937
build (builder, state, getCallOpResultTypes (calleeType),
890
938
TypeAttr::get (calleeType), /* callee=*/ nullptr , args,
891
939
/* fastmathFlags=*/ nullptr , /* branch_weights=*/ nullptr ,
940
+ /* CConv=*/ nullptr ,
892
941
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
893
942
/* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
894
943
}
@@ -899,9 +948,11 @@ void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
899
948
build (builder, state, getCallOpResultTypes (calleeType),
900
949
TypeAttr::get (calleeType), SymbolRefAttr::get (func), args,
901
950
/* fastmathFlags=*/ nullptr , /* branch_weights=*/ nullptr ,
951
+ /* CConv=*/ nullptr ,
902
952
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
903
953
/* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
904
954
}
955
+
905
956
CallInterfaceCallable CallOp::getCallableForCallee () {
906
957
// Direct call.
907
958
if (FlatSymbolRefAttr calleeAttr = getCalleeAttr ())
@@ -1054,9 +1105,14 @@ void CallOp::print(OpAsmPrinter &p) {
1054
1105
isVarArg = calleeType.isVarArg ();
1055
1106
}
1056
1107
1108
+ p << ' ' ;
1109
+
1110
+ // Print calling convention.
1111
+ if (getCConv () != LLVM::CConv::C)
1112
+ p << stringifyCConv (getCConv ()) << ' ' ;
1113
+
1057
1114
// Print the direct callee if present as a function attribute, or an indirect
1058
1115
// callee (first operand) otherwise.
1059
- p << ' ' ;
1060
1116
if (isDirect)
1061
1117
p.printSymbolName (callee.value ());
1062
1118
else
@@ -1069,7 +1125,7 @@ void CallOp::print(OpAsmPrinter &p) {
1069
1125
p << " vararg(" << calleeType << " )" ;
1070
1126
1071
1127
p.printOptionalAttrDict (processFMFAttr ((*this )->getAttrs ()),
1072
- {" callee" , " callee_type" });
1128
+ {getCConvAttrName (), " callee" , " callee_type" });
1073
1129
1074
1130
p << " : " ;
1075
1131
if (!isDirect)
@@ -1137,7 +1193,7 @@ static ParseResult parseOptionalCallFuncPtr(
1137
1193
return success ();
1138
1194
}
1139
1195
1140
- // <operation> ::= `llvm.call` (function-id | ssa-use)
1196
+ // <operation> ::= `llvm.call` (cconv)? ( function-id | ssa-use)
1141
1197
// `(` ssa-use-list `)`
1142
1198
// ( `vararg(` var-arg-func-type `)` )?
1143
1199
// attribute-dict? `:` (type `,`)? function-type
@@ -1146,6 +1202,12 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
1146
1202
TypeAttr calleeType;
1147
1203
SmallVector<OpAsmParser::UnresolvedOperand> operands;
1148
1204
1205
+ // Default to C Calling Convention if no keyword is provided.
1206
+ result.addAttribute (
1207
+ getCConvAttrName (result.name ),
1208
+ CConvAttr::get (parser.getContext (), parseOptionalLLVMKeyword<CConv>(
1209
+ parser, result, LLVM::CConv::C)));
1210
+
1149
1211
// Parse a function pointer for indirect calls.
1150
1212
if (parseOptionalCallFuncPtr (parser, operands))
1151
1213
return failure ();
@@ -1191,7 +1253,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
1191
1253
auto calleeType = func.getFunctionType ();
1192
1254
build (builder, state, getCallOpResultTypes (calleeType),
1193
1255
TypeAttr::get (calleeType), SymbolRefAttr::get (func), ops, normalOps,
1194
- unwindOps, nullptr , normal, unwind);
1256
+ unwindOps, nullptr , nullptr , normal, unwind);
1195
1257
}
1196
1258
1197
1259
void InvokeOp::build (OpBuilder &builder, OperationState &state, TypeRange tys,
@@ -1200,7 +1262,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
1200
1262
ValueRange unwindOps) {
1201
1263
build (builder, state, tys,
1202
1264
TypeAttr::get (getLLVMFuncType (builder.getContext (), tys, ops)), callee,
1203
- ops, normalOps, unwindOps, nullptr , normal, unwind);
1265
+ ops, normalOps, unwindOps, nullptr , nullptr , normal, unwind);
1204
1266
}
1205
1267
1206
1268
void InvokeOp::build (OpBuilder &builder, OperationState &state,
@@ -1209,7 +1271,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
1209
1271
Block *unwind, ValueRange unwindOps) {
1210
1272
build (builder, state, getCallOpResultTypes (calleeType),
1211
1273
TypeAttr::get (calleeType), callee, ops, normalOps, unwindOps, nullptr ,
1212
- normal, unwind);
1274
+ nullptr , normal, unwind);
1213
1275
}
1214
1276
1215
1277
SuccessorOperands InvokeOp::getSuccessorOperands (unsigned index) {
@@ -1275,6 +1337,10 @@ void InvokeOp::print(OpAsmPrinter &p) {
1275
1337
1276
1338
p << ' ' ;
1277
1339
1340
+ // Print calling convention.
1341
+ if (getCConv () != LLVM::CConv::C)
1342
+ p << stringifyCConv (getCConv ()) << ' ' ;
1343
+
1278
1344
// Either function name or pointer
1279
1345
if (isDirect)
1280
1346
p.printSymbolName (callee.value ());
@@ -1290,9 +1356,9 @@ void InvokeOp::print(OpAsmPrinter &p) {
1290
1356
if (isVarArg)
1291
1357
p << " vararg(" << calleeType << " )" ;
1292
1358
1293
- p.printOptionalAttrDict (
1294
- (* this )-> getAttrs () ,
1295
- { InvokeOp::getOperandSegmentSizeAttr (), " callee " , " callee_type" });
1359
+ p.printOptionalAttrDict ((* this )-> getAttrs (),
1360
+ { InvokeOp::getOperandSegmentSizeAttr (), " callee " ,
1361
+ " callee_type" , InvokeOp::getCConvAttrName () });
1296
1362
1297
1363
p << " : " ;
1298
1364
if (!isDirect)
@@ -1301,7 +1367,7 @@ void InvokeOp::print(OpAsmPrinter &p) {
1301
1367
getResultTypes ());
1302
1368
}
1303
1369
1304
- // <operation> ::= `llvm.invoke` (function-id | ssa-use)
1370
+ // <operation> ::= `llvm.invoke` (cconv)? ( function-id | ssa-use)
1305
1371
// `(` ssa-use-list `)`
1306
1372
// `to` bb-id (`[` ssa-use-and-type-list `]`)?
1307
1373
// `unwind` bb-id (`[` ssa-use-and-type-list `]`)?
@@ -1315,6 +1381,12 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
1315
1381
SmallVector<Value, 4 > normalOperands, unwindOperands;
1316
1382
Builder &builder = parser.getBuilder ();
1317
1383
1384
+ // Default to C Calling Convention if no keyword is provided.
1385
+ result.addAttribute (
1386
+ getCConvAttrName (result.name ),
1387
+ CConvAttr::get (parser.getContext (), parseOptionalLLVMKeyword<CConv>(
1388
+ parser, result, LLVM::CConv::C)));
1389
+
1318
1390
// Parse a function pointer for indirect calls.
1319
1391
if (parseOptionalCallFuncPtr (parser, operands))
1320
1392
return failure ();
@@ -1788,52 +1860,6 @@ void GlobalOp::print(OpAsmPrinter &p) {
1788
1860
}
1789
1861
}
1790
1862
1791
- // Parses one of the keywords provided in the list `keywords` and returns the
1792
- // position of the parsed keyword in the list. If none of the keywords from the
1793
- // list is parsed, returns -1.
1794
- static int parseOptionalKeywordAlternative (OpAsmParser &parser,
1795
- ArrayRef<StringRef> keywords) {
1796
- for (const auto &en : llvm::enumerate (keywords)) {
1797
- if (succeeded (parser.parseOptionalKeyword (en.value ())))
1798
- return en.index ();
1799
- }
1800
- return -1 ;
1801
- }
1802
-
1803
- namespace {
1804
- template <typename Ty>
1805
- struct EnumTraits {};
1806
-
1807
- #define REGISTER_ENUM_TYPE (Ty ) \
1808
- template <> \
1809
- struct EnumTraits <Ty> { \
1810
- static StringRef stringify (Ty value) { return stringify##Ty (value); } \
1811
- static unsigned getMaxEnumVal () { return getMaxEnumValFor##Ty (); } \
1812
- }
1813
-
1814
- REGISTER_ENUM_TYPE (Linkage);
1815
- REGISTER_ENUM_TYPE (UnnamedAddr);
1816
- REGISTER_ENUM_TYPE (CConv);
1817
- REGISTER_ENUM_TYPE (Visibility);
1818
- } // namespace
1819
-
1820
- // / Parse an enum from the keyword, or default to the provided default value.
1821
- // / The return type is the enum type by default, unless overriden with the
1822
- // / second template argument.
1823
- template <typename EnumTy, typename RetTy = EnumTy>
1824
- static RetTy parseOptionalLLVMKeyword (OpAsmParser &parser,
1825
- OperationState &result,
1826
- EnumTy defaultValue) {
1827
- SmallVector<StringRef, 10 > names;
1828
- for (unsigned i = 0 , e = EnumTraits<EnumTy>::getMaxEnumVal (); i <= e; ++i)
1829
- names.push_back (EnumTraits<EnumTy>::stringify (static_cast <EnumTy>(i)));
1830
-
1831
- int index = parseOptionalKeywordAlternative (parser, names);
1832
- if (index == -1 )
1833
- return static_cast <RetTy>(defaultValue);
1834
- return static_cast <RetTy>(index);
1835
- }
1836
-
1837
1863
static LogicalResult verifyComdat (Operation *op,
1838
1864
std::optional<SymbolRefAttr> attr) {
1839
1865
if (!attr)
0 commit comments