1 //===- LLVMDialect.cpp - LLVM IR Ops and Dialect registration -------------===//
2 //
3 // Part of the MLIR 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 // This file defines the types and operation details for the LLVM IR dialect in
10 // MLIR, and the LLVM IR dialect.  It also registers the dialect.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
14 #include "mlir/IR/Builders.h"
15 #include "mlir/IR/DialectImplementation.h"
16 #include "mlir/IR/FunctionImplementation.h"
17 #include "mlir/IR/MLIRContext.h"
18 #include "mlir/IR/Module.h"
19 #include "mlir/IR/StandardTypes.h"
20 
21 #include "llvm/AsmParser/Parser.h"
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/Type.h"
25 #include "llvm/Support/Mutex.h"
26 #include "llvm/Support/SourceMgr.h"
27 
28 using namespace mlir;
29 using namespace mlir::LLVM;
30 
31 #include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
32 
33 //===----------------------------------------------------------------------===//
34 // Printing/parsing for LLVM::CmpOp.
35 //===----------------------------------------------------------------------===//
36 static void printICmpOp(OpAsmPrinter &p, ICmpOp &op) {
37   p << op.getOperationName() << " \"" << stringifyICmpPredicate(op.predicate())
38     << "\" " << op.getOperand(0) << ", " << op.getOperand(1);
39   p.printOptionalAttrDict(op.getAttrs(), {"predicate"});
40   p << " : " << op.lhs().getType();
41 }
42 
43 static void printFCmpOp(OpAsmPrinter &p, FCmpOp &op) {
44   p << op.getOperationName() << " \"" << stringifyFCmpPredicate(op.predicate())
45     << "\" " << op.getOperand(0) << ", " << op.getOperand(1);
46   p.printOptionalAttrDict(op.getAttrs(), {"predicate"});
47   p << " : " << op.lhs().getType();
48 }
49 
50 // <operation> ::= `llvm.icmp` string-literal ssa-use `,` ssa-use
51 //                 attribute-dict? `:` type
52 // <operation> ::= `llvm.fcmp` string-literal ssa-use `,` ssa-use
53 //                 attribute-dict? `:` type
54 template <typename CmpPredicateType>
55 static ParseResult parseCmpOp(OpAsmParser &parser, OperationState &result) {
56   Builder &builder = parser.getBuilder();
57 
58   Attribute predicate;
59   SmallVector<NamedAttribute, 4> attrs;
60   OpAsmParser::OperandType lhs, rhs;
61   Type type;
62   llvm::SMLoc predicateLoc, trailingTypeLoc;
63   if (parser.getCurrentLocation(&predicateLoc) ||
64       parser.parseAttribute(predicate, "predicate", attrs) ||
65       parser.parseOperand(lhs) || parser.parseComma() ||
66       parser.parseOperand(rhs) || parser.parseOptionalAttrDict(attrs) ||
67       parser.parseColon() || parser.getCurrentLocation(&trailingTypeLoc) ||
68       parser.parseType(type) ||
69       parser.resolveOperand(lhs, type, result.operands) ||
70       parser.resolveOperand(rhs, type, result.operands))
71     return failure();
72 
73   // Replace the string attribute `predicate` with an integer attribute.
74   auto predicateStr = predicate.dyn_cast<StringAttr>();
75   if (!predicateStr)
76     return parser.emitError(predicateLoc,
77                             "expected 'predicate' attribute of string type");
78 
79   int64_t predicateValue = 0;
80   if (std::is_same<CmpPredicateType, ICmpPredicate>()) {
81     Optional<ICmpPredicate> predicate =
82         symbolizeICmpPredicate(predicateStr.getValue());
83     if (!predicate)
84       return parser.emitError(predicateLoc)
85              << "'" << predicateStr.getValue()
86              << "' is an incorrect value of the 'predicate' attribute";
87     predicateValue = static_cast<int64_t>(predicate.getValue());
88   } else {
89     Optional<FCmpPredicate> predicate =
90         symbolizeFCmpPredicate(predicateStr.getValue());
91     if (!predicate)
92       return parser.emitError(predicateLoc)
93              << "'" << predicateStr.getValue()
94              << "' is an incorrect value of the 'predicate' attribute";
95     predicateValue = static_cast<int64_t>(predicate.getValue());
96   }
97 
98   attrs[0].second = parser.getBuilder().getI64IntegerAttr(predicateValue);
99 
100   // The result type is either i1 or a vector type <? x i1> if the inputs are
101   // vectors.
102   auto *dialect = builder.getContext()->getRegisteredDialect<LLVMDialect>();
103   auto resultType = LLVMType::getInt1Ty(dialect);
104   auto argType = type.dyn_cast<LLVM::LLVMType>();
105   if (!argType)
106     return parser.emitError(trailingTypeLoc, "expected LLVM IR dialect type");
107   if (argType.getUnderlyingType()->isVectorTy())
108     resultType = LLVMType::getVectorTy(
109         resultType, argType.getUnderlyingType()->getVectorNumElements());
110 
111   result.attributes = attrs;
112   result.addTypes({resultType});
113   return success();
114 }
115 
116 //===----------------------------------------------------------------------===//
117 // Printing/parsing for LLVM::AllocaOp.
118 //===----------------------------------------------------------------------===//
119 
120 static void printAllocaOp(OpAsmPrinter &p, AllocaOp &op) {
121   auto elemTy = op.getType().cast<LLVM::LLVMType>().getPointerElementTy();
122 
123   auto funcTy = FunctionType::get({op.arraySize().getType()}, {op.getType()},
124                                   op.getContext());
125 
126   p << op.getOperationName() << ' ' << op.arraySize() << " x " << elemTy;
127   if (op.alignment().hasValue() && op.alignment()->getSExtValue() != 0)
128     p.printOptionalAttrDict(op.getAttrs());
129   else
130     p.printOptionalAttrDict(op.getAttrs(), {"alignment"});
131   p << " : " << funcTy;
132 }
133 
134 // <operation> ::= `llvm.alloca` ssa-use `x` type attribute-dict?
135 //                 `:` type `,` type
136 static ParseResult parseAllocaOp(OpAsmParser &parser, OperationState &result) {
137   SmallVector<NamedAttribute, 4> attrs;
138   OpAsmParser::OperandType arraySize;
139   Type type, elemType;
140   llvm::SMLoc trailingTypeLoc;
141   if (parser.parseOperand(arraySize) || parser.parseKeyword("x") ||
142       parser.parseType(elemType) || parser.parseOptionalAttrDict(attrs) ||
143       parser.parseColon() || parser.getCurrentLocation(&trailingTypeLoc) ||
144       parser.parseType(type))
145     return failure();
146 
147   // Extract the result type from the trailing function type.
148   auto funcType = type.dyn_cast<FunctionType>();
149   if (!funcType || funcType.getNumInputs() != 1 ||
150       funcType.getNumResults() != 1)
151     return parser.emitError(
152         trailingTypeLoc,
153         "expected trailing function type with one argument and one result");
154 
155   if (parser.resolveOperand(arraySize, funcType.getInput(0), result.operands))
156     return failure();
157 
158   result.attributes = attrs;
159   result.addTypes({funcType.getResult(0)});
160   return success();
161 }
162 
163 //===----------------------------------------------------------------------===//
164 // Printing/parsing for LLVM::GEPOp.
165 //===----------------------------------------------------------------------===//
166 
167 static void printGEPOp(OpAsmPrinter &p, GEPOp &op) {
168   SmallVector<Type, 8> types(op.getOperandTypes());
169   auto funcTy = FunctionType::get(types, op.getType(), op.getContext());
170 
171   p << op.getOperationName() << ' ' << op.base() << '['
172     << op.getOperands().drop_front() << ']';
173   p.printOptionalAttrDict(op.getAttrs());
174   p << " : " << funcTy;
175 }
176 
177 // <operation> ::= `llvm.getelementptr` ssa-use `[` ssa-use-list `]`
178 //                 attribute-dict? `:` type
179 static ParseResult parseGEPOp(OpAsmParser &parser, OperationState &result) {
180   SmallVector<NamedAttribute, 4> attrs;
181   OpAsmParser::OperandType base;
182   SmallVector<OpAsmParser::OperandType, 8> indices;
183   Type type;
184   llvm::SMLoc trailingTypeLoc;
185   if (parser.parseOperand(base) ||
186       parser.parseOperandList(indices, OpAsmParser::Delimiter::Square) ||
187       parser.parseOptionalAttrDict(attrs) || parser.parseColon() ||
188       parser.getCurrentLocation(&trailingTypeLoc) || parser.parseType(type))
189     return failure();
190 
191   // Deconstruct the trailing function type to extract the types of the base
192   // pointer and result (same type) and the types of the indices.
193   auto funcType = type.dyn_cast<FunctionType>();
194   if (!funcType || funcType.getNumResults() != 1 ||
195       funcType.getNumInputs() == 0)
196     return parser.emitError(trailingTypeLoc,
197                             "expected trailing function type with at least "
198                             "one argument and one result");
199 
200   if (parser.resolveOperand(base, funcType.getInput(0), result.operands) ||
201       parser.resolveOperands(indices, funcType.getInputs().drop_front(),
202                              parser.getNameLoc(), result.operands))
203     return failure();
204 
205   result.attributes = attrs;
206   result.addTypes(funcType.getResults());
207   return success();
208 }
209 
210 //===----------------------------------------------------------------------===//
211 // Printing/parsing for LLVM::LoadOp.
212 //===----------------------------------------------------------------------===//
213 
214 static void printLoadOp(OpAsmPrinter &p, LoadOp &op) {
215   p << op.getOperationName() << ' ' << op.addr();
216   p.printOptionalAttrDict(op.getAttrs());
217   p << " : " << op.addr().getType();
218 }
219 
220 // Extract the pointee type from the LLVM pointer type wrapped in MLIR.  Return
221 // the resulting type wrapped in MLIR, or nullptr on error.
222 static Type getLoadStoreElementType(OpAsmParser &parser, Type type,
223                                     llvm::SMLoc trailingTypeLoc) {
224   auto llvmTy = type.dyn_cast<LLVM::LLVMType>();
225   if (!llvmTy)
226     return parser.emitError(trailingTypeLoc, "expected LLVM IR dialect type"),
227            nullptr;
228   if (!llvmTy.getUnderlyingType()->isPointerTy())
229     return parser.emitError(trailingTypeLoc, "expected LLVM pointer type"),
230            nullptr;
231   return llvmTy.getPointerElementTy();
232 }
233 
234 // <operation> ::= `llvm.load` ssa-use attribute-dict? `:` type
235 static ParseResult parseLoadOp(OpAsmParser &parser, OperationState &result) {
236   SmallVector<NamedAttribute, 4> attrs;
237   OpAsmParser::OperandType addr;
238   Type type;
239   llvm::SMLoc trailingTypeLoc;
240 
241   if (parser.parseOperand(addr) || parser.parseOptionalAttrDict(attrs) ||
242       parser.parseColon() || parser.getCurrentLocation(&trailingTypeLoc) ||
243       parser.parseType(type) ||
244       parser.resolveOperand(addr, type, result.operands))
245     return failure();
246 
247   Type elemTy = getLoadStoreElementType(parser, type, trailingTypeLoc);
248 
249   result.attributes = attrs;
250   result.addTypes(elemTy);
251   return success();
252 }
253 
254 //===----------------------------------------------------------------------===//
255 // Printing/parsing for LLVM::StoreOp.
256 //===----------------------------------------------------------------------===//
257 
258 static void printStoreOp(OpAsmPrinter &p, StoreOp &op) {
259   p << op.getOperationName() << ' ' << op.value() << ", " << op.addr();
260   p.printOptionalAttrDict(op.getAttrs());
261   p << " : " << op.addr().getType();
262 }
263 
264 // <operation> ::= `llvm.store` ssa-use `,` ssa-use attribute-dict? `:` type
265 static ParseResult parseStoreOp(OpAsmParser &parser, OperationState &result) {
266   SmallVector<NamedAttribute, 4> attrs;
267   OpAsmParser::OperandType addr, value;
268   Type type;
269   llvm::SMLoc trailingTypeLoc;
270 
271   if (parser.parseOperand(value) || parser.parseComma() ||
272       parser.parseOperand(addr) || parser.parseOptionalAttrDict(attrs) ||
273       parser.parseColon() || parser.getCurrentLocation(&trailingTypeLoc) ||
274       parser.parseType(type))
275     return failure();
276 
277   Type elemTy = getLoadStoreElementType(parser, type, trailingTypeLoc);
278   if (!elemTy)
279     return failure();
280 
281   if (parser.resolveOperand(value, elemTy, result.operands) ||
282       parser.resolveOperand(addr, type, result.operands))
283     return failure();
284 
285   result.attributes = attrs;
286   return success();
287 }
288 
289 //===----------------------------------------------------------------------===//
290 // Printing/parsing for LLVM::CallOp.
291 //===----------------------------------------------------------------------===//
292 
293 static void printCallOp(OpAsmPrinter &p, CallOp &op) {
294   auto callee = op.callee();
295   bool isDirect = callee.hasValue();
296 
297   // Print the direct callee if present as a function attribute, or an indirect
298   // callee (first operand) otherwise.
299   p << op.getOperationName() << ' ';
300   if (isDirect)
301     p.printSymbolName(callee.getValue());
302   else
303     p << op.getOperand(0);
304 
305   p << '(' << op.getOperands().drop_front(isDirect ? 0 : 1) << ')';
306   p.printOptionalAttrDict(op.getAttrs(), {"callee"});
307 
308   // Reconstruct the function MLIR function type from operand and result types.
309   SmallVector<Type, 1> resultTypes(op.getResultTypes());
310   SmallVector<Type, 8> argTypes(
311       llvm::drop_begin(op.getOperandTypes(), isDirect ? 0 : 1));
312 
313   p << " : " << FunctionType::get(argTypes, resultTypes, op.getContext());
314 }
315 
316 // <operation> ::= `llvm.call` (function-id | ssa-use) `(` ssa-use-list `)`
317 //                 attribute-dict? `:` function-type
318 static ParseResult parseCallOp(OpAsmParser &parser, OperationState &result) {
319   SmallVector<NamedAttribute, 4> attrs;
320   SmallVector<OpAsmParser::OperandType, 8> operands;
321   Type type;
322   SymbolRefAttr funcAttr;
323   llvm::SMLoc trailingTypeLoc;
324 
325   // Parse an operand list that will, in practice, contain 0 or 1 operand.  In
326   // case of an indirect call, there will be 1 operand before `(`.  In case of a
327   // direct call, there will be no operands and the parser will stop at the
328   // function identifier without complaining.
329   if (parser.parseOperandList(operands))
330     return failure();
331   bool isDirect = operands.empty();
332 
333   // Optionally parse a function identifier.
334   if (isDirect)
335     if (parser.parseAttribute(funcAttr, "callee", attrs))
336       return failure();
337 
338   if (parser.parseOperandList(operands, OpAsmParser::Delimiter::Paren) ||
339       parser.parseOptionalAttrDict(attrs) || parser.parseColon() ||
340       parser.getCurrentLocation(&trailingTypeLoc) || parser.parseType(type))
341     return failure();
342 
343   auto funcType = type.dyn_cast<FunctionType>();
344   if (!funcType)
345     return parser.emitError(trailingTypeLoc, "expected function type");
346   if (isDirect) {
347     // Make sure types match.
348     if (parser.resolveOperands(operands, funcType.getInputs(),
349                                parser.getNameLoc(), result.operands))
350       return failure();
351     result.addTypes(funcType.getResults());
352   } else {
353     // Construct the LLVM IR Dialect function type that the first operand
354     // should match.
355     if (funcType.getNumResults() > 1)
356       return parser.emitError(trailingTypeLoc,
357                               "expected function with 0 or 1 result");
358 
359     Builder &builder = parser.getBuilder();
360     auto *llvmDialect =
361         builder.getContext()->getRegisteredDialect<LLVM::LLVMDialect>();
362     LLVM::LLVMType llvmResultType;
363     if (funcType.getNumResults() == 0) {
364       llvmResultType = LLVM::LLVMType::getVoidTy(llvmDialect);
365     } else {
366       llvmResultType = funcType.getResult(0).dyn_cast<LLVM::LLVMType>();
367       if (!llvmResultType)
368         return parser.emitError(trailingTypeLoc,
369                                 "expected result to have LLVM type");
370     }
371 
372     SmallVector<LLVM::LLVMType, 8> argTypes;
373     argTypes.reserve(funcType.getNumInputs());
374     for (int i = 0, e = funcType.getNumInputs(); i < e; ++i) {
375       auto argType = funcType.getInput(i).dyn_cast<LLVM::LLVMType>();
376       if (!argType)
377         return parser.emitError(trailingTypeLoc,
378                                 "expected LLVM types as inputs");
379       argTypes.push_back(argType);
380     }
381     auto llvmFuncType = LLVM::LLVMType::getFunctionTy(llvmResultType, argTypes,
382                                                       /*isVarArg=*/false);
383     auto wrappedFuncType = llvmFuncType.getPointerTo();
384 
385     auto funcArguments =
386         ArrayRef<OpAsmParser::OperandType>(operands).drop_front();
387 
388     // Make sure that the first operand (indirect callee) matches the wrapped
389     // LLVM IR function type, and that the types of the other call operands
390     // match the types of the function arguments.
391     if (parser.resolveOperand(operands[0], wrappedFuncType, result.operands) ||
392         parser.resolveOperands(funcArguments, funcType.getInputs(),
393                                parser.getNameLoc(), result.operands))
394       return failure();
395 
396     result.addTypes(llvmResultType);
397   }
398 
399   result.attributes = attrs;
400   return success();
401 }
402 
403 //===----------------------------------------------------------------------===//
404 // Printing/parsing for LLVM::ExtractElementOp.
405 //===----------------------------------------------------------------------===//
406 // Expects vector to be of wrapped LLVM vector type and position to be of
407 // wrapped LLVM i32 type.
408 void LLVM::ExtractElementOp::build(Builder *b, OperationState &result,
409                                    Value vector, Value position,
410                                    ArrayRef<NamedAttribute> attrs) {
411   auto wrappedVectorType = vector.getType().cast<LLVM::LLVMType>();
412   auto llvmType = wrappedVectorType.getVectorElementType();
413   build(b, result, llvmType, vector, position);
414   result.addAttributes(attrs);
415 }
416 
417 static void printExtractElementOp(OpAsmPrinter &p, ExtractElementOp &op) {
418   p << op.getOperationName() << ' ' << op.vector() << "[" << op.position()
419     << " : " << op.position().getType() << "]";
420   p.printOptionalAttrDict(op.getAttrs());
421   p << " : " << op.vector().getType();
422 }
423 
424 // <operation> ::= `llvm.extractelement` ssa-use `, ` ssa-use
425 //                 attribute-dict? `:` type
426 static ParseResult parseExtractElementOp(OpAsmParser &parser,
427                                          OperationState &result) {
428   llvm::SMLoc loc;
429   OpAsmParser::OperandType vector, position;
430   Type type, positionType;
431   if (parser.getCurrentLocation(&loc) || parser.parseOperand(vector) ||
432       parser.parseLSquare() || parser.parseOperand(position) ||
433       parser.parseColonType(positionType) || parser.parseRSquare() ||
434       parser.parseOptionalAttrDict(result.attributes) ||
435       parser.parseColonType(type) ||
436       parser.resolveOperand(vector, type, result.operands) ||
437       parser.resolveOperand(position, positionType, result.operands))
438     return failure();
439   auto wrappedVectorType = type.dyn_cast<LLVM::LLVMType>();
440   if (!wrappedVectorType ||
441       !wrappedVectorType.getUnderlyingType()->isVectorTy())
442     return parser.emitError(
443         loc, "expected LLVM IR dialect vector type for operand #1");
444   result.addTypes(wrappedVectorType.getVectorElementType());
445   return success();
446 }
447 
448 //===----------------------------------------------------------------------===//
449 // Printing/parsing for LLVM::ExtractValueOp.
450 //===----------------------------------------------------------------------===//
451 
452 static void printExtractValueOp(OpAsmPrinter &p, ExtractValueOp &op) {
453   p << op.getOperationName() << ' ' << op.container() << op.position();
454   p.printOptionalAttrDict(op.getAttrs(), {"position"});
455   p << " : " << op.container().getType();
456 }
457 
458 // Extract the type at `position` in the wrapped LLVM IR aggregate type
459 // `containerType`.  Position is an integer array attribute where each value
460 // is a zero-based position of the element in the aggregate type.  Return the
461 // resulting type wrapped in MLIR, or nullptr on error.
462 static LLVM::LLVMType getInsertExtractValueElementType(OpAsmParser &parser,
463                                                        Type containerType,
464                                                        Attribute positionAttr,
465                                                        llvm::SMLoc attributeLoc,
466                                                        llvm::SMLoc typeLoc) {
467   auto wrappedContainerType = containerType.dyn_cast<LLVM::LLVMType>();
468   if (!wrappedContainerType)
469     return parser.emitError(typeLoc, "expected LLVM IR Dialect type"), nullptr;
470 
471   auto positionArrayAttr = positionAttr.dyn_cast<ArrayAttr>();
472   if (!positionArrayAttr)
473     return parser.emitError(attributeLoc, "expected an array attribute"),
474            nullptr;
475 
476   // Infer the element type from the structure type: iteratively step inside the
477   // type by taking the element type, indexed by the position attribute for
478   // structures.  Check the position index before accessing, it is supposed to
479   // be in bounds.
480   for (Attribute subAttr : positionArrayAttr) {
481     auto positionElementAttr = subAttr.dyn_cast<IntegerAttr>();
482     if (!positionElementAttr)
483       return parser.emitError(attributeLoc,
484                               "expected an array of integer literals"),
485              nullptr;
486     int position = positionElementAttr.getInt();
487     auto *llvmContainerType = wrappedContainerType.getUnderlyingType();
488     if (llvmContainerType->isArrayTy()) {
489       if (position < 0 || static_cast<unsigned>(position) >=
490                               llvmContainerType->getArrayNumElements())
491         return parser.emitError(attributeLoc, "position out of bounds"),
492                nullptr;
493       wrappedContainerType = wrappedContainerType.getArrayElementType();
494     } else if (llvmContainerType->isStructTy()) {
495       if (position < 0 || static_cast<unsigned>(position) >=
496                               llvmContainerType->getStructNumElements())
497         return parser.emitError(attributeLoc, "position out of bounds"),
498                nullptr;
499       wrappedContainerType =
500           wrappedContainerType.getStructElementType(position);
501     } else {
502       return parser.emitError(typeLoc,
503                               "expected wrapped LLVM IR structure/array type"),
504              nullptr;
505     }
506   }
507   return wrappedContainerType;
508 }
509 
510 // <operation> ::= `llvm.extractvalue` ssa-use
511 //                 `[` integer-literal (`,` integer-literal)* `]`
512 //                 attribute-dict? `:` type
513 static ParseResult parseExtractValueOp(OpAsmParser &parser,
514                                        OperationState &result) {
515   SmallVector<NamedAttribute, 4> attrs;
516   OpAsmParser::OperandType container;
517   Type containerType;
518   Attribute positionAttr;
519   llvm::SMLoc attributeLoc, trailingTypeLoc;
520 
521   if (parser.parseOperand(container) ||
522       parser.getCurrentLocation(&attributeLoc) ||
523       parser.parseAttribute(positionAttr, "position", attrs) ||
524       parser.parseOptionalAttrDict(attrs) || parser.parseColon() ||
525       parser.getCurrentLocation(&trailingTypeLoc) ||
526       parser.parseType(containerType) ||
527       parser.resolveOperand(container, containerType, result.operands))
528     return failure();
529 
530   auto elementType = getInsertExtractValueElementType(
531       parser, containerType, positionAttr, attributeLoc, trailingTypeLoc);
532   if (!elementType)
533     return failure();
534 
535   result.attributes = attrs;
536   result.addTypes(elementType);
537   return success();
538 }
539 
540 //===----------------------------------------------------------------------===//
541 // Printing/parsing for LLVM::InsertElementOp.
542 //===----------------------------------------------------------------------===//
543 
544 static void printInsertElementOp(OpAsmPrinter &p, InsertElementOp &op) {
545   p << op.getOperationName() << ' ' << op.value() << ", " << op.vector() << "["
546     << op.position() << " : " << op.position().getType() << "]";
547   p.printOptionalAttrDict(op.getAttrs());
548   p << " : " << op.vector().getType();
549 }
550 
551 // <operation> ::= `llvm.insertelement` ssa-use `,` ssa-use `,` ssa-use
552 //                 attribute-dict? `:` type
553 static ParseResult parseInsertElementOp(OpAsmParser &parser,
554                                         OperationState &result) {
555   llvm::SMLoc loc;
556   OpAsmParser::OperandType vector, value, position;
557   Type vectorType, positionType;
558   if (parser.getCurrentLocation(&loc) || parser.parseOperand(value) ||
559       parser.parseComma() || parser.parseOperand(vector) ||
560       parser.parseLSquare() || parser.parseOperand(position) ||
561       parser.parseColonType(positionType) || parser.parseRSquare() ||
562       parser.parseOptionalAttrDict(result.attributes) ||
563       parser.parseColonType(vectorType))
564     return failure();
565 
566   auto wrappedVectorType = vectorType.dyn_cast<LLVM::LLVMType>();
567   if (!wrappedVectorType ||
568       !wrappedVectorType.getUnderlyingType()->isVectorTy())
569     return parser.emitError(
570         loc, "expected LLVM IR dialect vector type for operand #1");
571   auto valueType = wrappedVectorType.getVectorElementType();
572   if (!valueType)
573     return failure();
574 
575   if (parser.resolveOperand(vector, vectorType, result.operands) ||
576       parser.resolveOperand(value, valueType, result.operands) ||
577       parser.resolveOperand(position, positionType, result.operands))
578     return failure();
579 
580   result.addTypes(vectorType);
581   return success();
582 }
583 
584 //===----------------------------------------------------------------------===//
585 // Printing/parsing for LLVM::InsertValueOp.
586 //===----------------------------------------------------------------------===//
587 
588 static void printInsertValueOp(OpAsmPrinter &p, InsertValueOp &op) {
589   p << op.getOperationName() << ' ' << op.value() << ", " << op.container()
590     << op.position();
591   p.printOptionalAttrDict(op.getAttrs(), {"position"});
592   p << " : " << op.container().getType();
593 }
594 
595 // <operation> ::= `llvm.insertvaluevalue` ssa-use `,` ssa-use
596 //                 `[` integer-literal (`,` integer-literal)* `]`
597 //                 attribute-dict? `:` type
598 static ParseResult parseInsertValueOp(OpAsmParser &parser,
599                                       OperationState &result) {
600   OpAsmParser::OperandType container, value;
601   Type containerType;
602   Attribute positionAttr;
603   llvm::SMLoc attributeLoc, trailingTypeLoc;
604 
605   if (parser.parseOperand(value) || parser.parseComma() ||
606       parser.parseOperand(container) ||
607       parser.getCurrentLocation(&attributeLoc) ||
608       parser.parseAttribute(positionAttr, "position", result.attributes) ||
609       parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
610       parser.getCurrentLocation(&trailingTypeLoc) ||
611       parser.parseType(containerType))
612     return failure();
613 
614   auto valueType = getInsertExtractValueElementType(
615       parser, containerType, positionAttr, attributeLoc, trailingTypeLoc);
616   if (!valueType)
617     return failure();
618 
619   if (parser.resolveOperand(container, containerType, result.operands) ||
620       parser.resolveOperand(value, valueType, result.operands))
621     return failure();
622 
623   result.addTypes(containerType);
624   return success();
625 }
626 
627 //===----------------------------------------------------------------------===//
628 // Printing/parsing for LLVM::SelectOp.
629 //===----------------------------------------------------------------------===//
630 
631 static void printSelectOp(OpAsmPrinter &p, SelectOp &op) {
632   p << op.getOperationName() << ' ' << op.condition() << ", " << op.trueValue()
633     << ", " << op.falseValue();
634   p.printOptionalAttrDict(op.getAttrs());
635   p << " : " << op.condition().getType() << ", " << op.trueValue().getType();
636 }
637 
638 // <operation> ::= `llvm.select` ssa-use `,` ssa-use `,` ssa-use
639 //                 attribute-dict? `:` type, type
640 static ParseResult parseSelectOp(OpAsmParser &parser, OperationState &result) {
641   OpAsmParser::OperandType condition, trueValue, falseValue;
642   Type conditionType, argType;
643 
644   if (parser.parseOperand(condition) || parser.parseComma() ||
645       parser.parseOperand(trueValue) || parser.parseComma() ||
646       parser.parseOperand(falseValue) ||
647       parser.parseOptionalAttrDict(result.attributes) ||
648       parser.parseColonType(conditionType) || parser.parseComma() ||
649       parser.parseType(argType))
650     return failure();
651 
652   if (parser.resolveOperand(condition, conditionType, result.operands) ||
653       parser.resolveOperand(trueValue, argType, result.operands) ||
654       parser.resolveOperand(falseValue, argType, result.operands))
655     return failure();
656 
657   result.addTypes(argType);
658   return success();
659 }
660 
661 //===----------------------------------------------------------------------===//
662 // Printing/parsing for LLVM::BrOp.
663 //===----------------------------------------------------------------------===//
664 
665 static void printBrOp(OpAsmPrinter &p, BrOp &op) {
666   p << op.getOperationName() << ' ';
667   p.printSuccessorAndUseList(op.getOperation(), 0);
668   p.printOptionalAttrDict(op.getAttrs());
669 }
670 
671 // <operation> ::= `llvm.br` bb-id (`[` ssa-use-and-type-list `]`)?
672 // attribute-dict?
673 static ParseResult parseBrOp(OpAsmParser &parser, OperationState &result) {
674   Block *dest;
675   SmallVector<Value, 4> operands;
676   if (parser.parseSuccessorAndUseList(dest, operands) ||
677       parser.parseOptionalAttrDict(result.attributes))
678     return failure();
679 
680   result.addSuccessor(dest, operands);
681   return success();
682 }
683 
684 //===----------------------------------------------------------------------===//
685 // Printing/parsing for LLVM::CondBrOp.
686 //===----------------------------------------------------------------------===//
687 
688 static void printCondBrOp(OpAsmPrinter &p, CondBrOp &op) {
689   p << op.getOperationName() << ' ' << op.getOperand(0) << ", ";
690   p.printSuccessorAndUseList(op.getOperation(), 0);
691   p << ", ";
692   p.printSuccessorAndUseList(op.getOperation(), 1);
693   p.printOptionalAttrDict(op.getAttrs());
694 }
695 
696 // <operation> ::= `llvm.cond_br` ssa-use `,`
697 //                  bb-id (`[` ssa-use-and-type-list `]`)? `,`
698 //                  bb-id (`[` ssa-use-and-type-list `]`)? attribute-dict?
699 static ParseResult parseCondBrOp(OpAsmParser &parser, OperationState &result) {
700   Block *trueDest;
701   Block *falseDest;
702   SmallVector<Value, 4> trueOperands;
703   SmallVector<Value, 4> falseOperands;
704   OpAsmParser::OperandType condition;
705 
706   Builder &builder = parser.getBuilder();
707   auto *llvmDialect =
708       builder.getContext()->getRegisteredDialect<LLVM::LLVMDialect>();
709   auto i1Type = LLVM::LLVMType::getInt1Ty(llvmDialect);
710 
711   if (parser.parseOperand(condition) || parser.parseComma() ||
712       parser.parseSuccessorAndUseList(trueDest, trueOperands) ||
713       parser.parseComma() ||
714       parser.parseSuccessorAndUseList(falseDest, falseOperands) ||
715       parser.parseOptionalAttrDict(result.attributes) ||
716       parser.resolveOperand(condition, i1Type, result.operands))
717     return failure();
718 
719   result.addSuccessor(trueDest, trueOperands);
720   result.addSuccessor(falseDest, falseOperands);
721   return success();
722 }
723 
724 //===----------------------------------------------------------------------===//
725 // Printing/parsing for LLVM::ReturnOp.
726 //===----------------------------------------------------------------------===//
727 
728 static void printReturnOp(OpAsmPrinter &p, ReturnOp &op) {
729   p << op.getOperationName();
730   p.printOptionalAttrDict(op.getAttrs());
731   assert(op.getNumOperands() <= 1);
732 
733   if (op.getNumOperands() == 0)
734     return;
735 
736   p << ' ' << op.getOperand(0) << " : " << op.getOperand(0).getType();
737 }
738 
739 // <operation> ::= `llvm.return` ssa-use-list attribute-dict? `:`
740 //                 type-list-no-parens
741 static ParseResult parseReturnOp(OpAsmParser &parser, OperationState &result) {
742   SmallVector<OpAsmParser::OperandType, 1> operands;
743   Type type;
744 
745   if (parser.parseOperandList(operands) ||
746       parser.parseOptionalAttrDict(result.attributes))
747     return failure();
748   if (operands.empty())
749     return success();
750 
751   if (parser.parseColonType(type) ||
752       parser.resolveOperand(operands[0], type, result.operands))
753     return failure();
754   return success();
755 }
756 
757 //===----------------------------------------------------------------------===//
758 // Printing/parsing for LLVM::UndefOp.
759 //===----------------------------------------------------------------------===//
760 
761 static void printUndefOp(OpAsmPrinter &p, UndefOp &op) {
762   p << op.getOperationName();
763   p.printOptionalAttrDict(op.getAttrs());
764   p << " : " << op.res().getType();
765 }
766 
767 // <operation> ::= `llvm.mlir.undef` attribute-dict? : type
768 static ParseResult parseUndefOp(OpAsmParser &parser, OperationState &result) {
769   Type type;
770 
771   if (parser.parseOptionalAttrDict(result.attributes) ||
772       parser.parseColonType(type))
773     return failure();
774 
775   result.addTypes(type);
776   return success();
777 }
778 
779 //===----------------------------------------------------------------------===//
780 // Printer, parser and verifier for LLVM::AddressOfOp.
781 //===----------------------------------------------------------------------===//
782 
783 GlobalOp AddressOfOp::getGlobal() {
784   Operation *module = getParentOp();
785   while (module && !satisfiesLLVMModule(module))
786     module = module->getParentOp();
787   assert(module && "unexpected operation outside of a module");
788   return dyn_cast_or_null<LLVM::GlobalOp>(
789       mlir::SymbolTable::lookupSymbolIn(module, global_name()));
790 }
791 
792 static void printAddressOfOp(OpAsmPrinter &p, AddressOfOp op) {
793   p << op.getOperationName() << " @" << op.global_name();
794   p.printOptionalAttrDict(op.getAttrs(), {"global_name"});
795   p << " : " << op.getResult().getType();
796 }
797 
798 static ParseResult parseAddressOfOp(OpAsmParser &parser,
799                                     OperationState &result) {
800   Attribute symRef;
801   Type type;
802   if (parser.parseAttribute(symRef, "global_name", result.attributes) ||
803       parser.parseOptionalAttrDict(result.attributes) ||
804       parser.parseColonType(type) || parser.addTypeToList(type, result.types))
805     return failure();
806 
807   if (!symRef.isa<SymbolRefAttr>())
808     return parser.emitError(parser.getNameLoc(), "expected symbol reference");
809   return success();
810 }
811 
812 static LogicalResult verify(AddressOfOp op) {
813   auto global = op.getGlobal();
814   if (!global)
815     return op.emitOpError(
816         "must reference a global defined by 'llvm.mlir.global'");
817 
818   if (global.getType().getPointerTo(global.addr_space().getZExtValue()) !=
819       op.getResult().getType())
820     return op.emitOpError(
821         "the type must be a pointer to the type of the referred global");
822 
823   return success();
824 }
825 
826 //===----------------------------------------------------------------------===//
827 // Printing/parsing for LLVM::ConstantOp.
828 //===----------------------------------------------------------------------===//
829 
830 static void printConstantOp(OpAsmPrinter &p, ConstantOp &op) {
831   p << op.getOperationName() << '(' << op.value() << ')';
832   p.printOptionalAttrDict(op.getAttrs(), {"value"});
833   p << " : " << op.res().getType();
834 }
835 
836 // <operation> ::= `llvm.mlir.constant` `(` attribute `)` attribute-list? : type
837 static ParseResult parseConstantOp(OpAsmParser &parser,
838                                    OperationState &result) {
839   Attribute valueAttr;
840   Type type;
841 
842   if (parser.parseLParen() ||
843       parser.parseAttribute(valueAttr, "value", result.attributes) ||
844       parser.parseRParen() || parser.parseOptionalAttrDict(result.attributes) ||
845       parser.parseColonType(type))
846     return failure();
847 
848   result.addTypes(type);
849   return success();
850 }
851 
852 //===----------------------------------------------------------------------===//
853 // Builder, printer and verifier for LLVM::GlobalOp.
854 //===----------------------------------------------------------------------===//
855 
856 /// Returns the name used for the linkge attribute. This *must* correspond to
857 /// the name of the attribute in ODS.
858 static StringRef getLinkageAttrName() { return "linkage"; }
859 
860 void GlobalOp::build(Builder *builder, OperationState &result, LLVMType type,
861                      bool isConstant, Linkage linkage, StringRef name,
862                      Attribute value, unsigned addrSpace,
863                      ArrayRef<NamedAttribute> attrs) {
864   result.addAttribute(SymbolTable::getSymbolAttrName(),
865                       builder->getStringAttr(name));
866   result.addAttribute("type", TypeAttr::get(type));
867   if (isConstant)
868     result.addAttribute("constant", builder->getUnitAttr());
869   if (value)
870     result.addAttribute("value", value);
871   result.addAttribute(getLinkageAttrName(), builder->getI64IntegerAttr(
872                                                 static_cast<int64_t>(linkage)));
873   if (addrSpace != 0)
874     result.addAttribute("addr_space", builder->getI32IntegerAttr(addrSpace));
875   result.attributes.append(attrs.begin(), attrs.end());
876   result.addRegion();
877 }
878 
879 // Returns the textual representation of the given linkage.
880 static StringRef linkageToStr(LLVM::Linkage linkage) {
881   switch (linkage) {
882   case LLVM::Linkage::Private:
883     return "private";
884   case LLVM::Linkage::Internal:
885     return "internal";
886   case LLVM::Linkage::AvailableExternally:
887     return "available_externally";
888   case LLVM::Linkage::Linkonce:
889     return "linkonce";
890   case LLVM::Linkage::Weak:
891     return "weak";
892   case LLVM::Linkage::Common:
893     return "common";
894   case LLVM::Linkage::Appending:
895     return "appending";
896   case LLVM::Linkage::ExternWeak:
897     return "extern_weak";
898   case LLVM::Linkage::LinkonceODR:
899     return "linkonce_odr";
900   case LLVM::Linkage::WeakODR:
901     return "weak_odr";
902   case LLVM::Linkage::External:
903     return "external";
904   }
905   llvm_unreachable("unknown linkage type");
906 }
907 
908 // Prints the keyword for the linkage type using the printer.
909 static void printLinkage(OpAsmPrinter &p, LLVM::Linkage linkage) {
910   p << linkageToStr(linkage);
911 }
912 
913 static void printGlobalOp(OpAsmPrinter &p, GlobalOp op) {
914   p << op.getOperationName() << ' ';
915   printLinkage(p, op.linkage());
916   p << ' ';
917   if (op.constant())
918     p << "constant ";
919   p.printSymbolName(op.sym_name());
920   p << '(';
921   if (auto value = op.getValueOrNull())
922     p.printAttribute(value);
923   p << ')';
924   p.printOptionalAttrDict(op.getAttrs(),
925                           {SymbolTable::getSymbolAttrName(), "type", "constant",
926                            "value", getLinkageAttrName()});
927 
928   // Print the trailing type unless it's a string global.
929   if (op.getValueOrNull().dyn_cast_or_null<StringAttr>())
930     return;
931   p << " : " << op.type();
932 
933   Region &initializer = op.getInitializerRegion();
934   if (!initializer.empty())
935     p.printRegion(initializer, /*printEntryBlockArgs=*/false);
936 }
937 
938 // Parses one of the keywords provided in the list `keywords` and returns the
939 // position of the parsed keyword in the list. If none of the keywords from the
940 // list is parsed, returns -1.
941 static int parseOptionalKeywordAlternative(OpAsmParser &parser,
942                                            ArrayRef<StringRef> keywords) {
943   for (auto en : llvm::enumerate(keywords)) {
944     if (succeeded(parser.parseOptionalKeyword(en.value())))
945       return en.index();
946   }
947   return -1;
948 }
949 
950 // Parses one of the linkage keywords and, if succeeded, appends the "linkage"
951 // integer attribute with the corresponding value to `result`.
952 //
953 // linkage ::= `private` | `internal` | `available_externally` | `linkonce`
954 //           | `weak` | `common` | `appending` | `extern_weak`
955 //           | `linkonce_odr` | `weak_odr` | `external
956 static ParseResult parseOptionalLinkageKeyword(OpAsmParser &parser,
957                                                OperationState &result) {
958   int index = parseOptionalKeywordAlternative(
959       parser, {"private", "internal", "available_externally", "linkonce",
960                "weak", "common", "appending", "extern_weak", "linkonce_odr",
961                "weak_odr", "external"});
962   if (index == -1)
963     return failure();
964   result.addAttribute(getLinkageAttrName(),
965                       parser.getBuilder().getI64IntegerAttr(index));
966   return success();
967 }
968 
969 // operation ::= `llvm.mlir.global` linkage `constant`? `@` identifier
970 //               `(` attribute? `)` attribute-list? (`:` type)? region?
971 //
972 // The type can be omitted for string attributes, in which case it will be
973 // inferred from the value of the string as [strlen(value) x i8].
974 static ParseResult parseGlobalOp(OpAsmParser &parser, OperationState &result) {
975   if (failed(parseOptionalLinkageKeyword(parser, result)))
976     return parser.emitError(parser.getCurrentLocation(), "expected linkage");
977 
978   if (succeeded(parser.parseOptionalKeyword("constant")))
979     result.addAttribute("constant", parser.getBuilder().getUnitAttr());
980 
981   StringAttr name;
982   if (parser.parseSymbolName(name, SymbolTable::getSymbolAttrName(),
983                              result.attributes) ||
984       parser.parseLParen())
985     return failure();
986 
987   Attribute value;
988   if (parser.parseOptionalRParen()) {
989     if (parser.parseAttribute(value, "value", result.attributes) ||
990         parser.parseRParen())
991       return failure();
992   }
993 
994   SmallVector<Type, 1> types;
995   if (parser.parseOptionalAttrDict(result.attributes) ||
996       parser.parseOptionalColonTypeList(types))
997     return failure();
998 
999   if (types.size() > 1)
1000     return parser.emitError(parser.getNameLoc(), "expected zero or one type");
1001 
1002   Region &initRegion = *result.addRegion();
1003   if (types.empty()) {
1004     if (auto strAttr = value.dyn_cast_or_null<StringAttr>()) {
1005       MLIRContext *context = parser.getBuilder().getContext();
1006       auto *dialect = context->getRegisteredDialect<LLVMDialect>();
1007       auto arrayType = LLVM::LLVMType::getArrayTy(
1008           LLVM::LLVMType::getInt8Ty(dialect), strAttr.getValue().size());
1009       types.push_back(arrayType);
1010     } else {
1011       return parser.emitError(parser.getNameLoc(),
1012                               "type can only be omitted for string globals");
1013     }
1014   } else if (parser.parseOptionalRegion(initRegion, /*arguments=*/{},
1015                                         /*argTypes=*/{})) {
1016     return failure();
1017   }
1018 
1019   result.addAttribute("type", TypeAttr::get(types[0]));
1020   return success();
1021 }
1022 
1023 static LogicalResult verify(GlobalOp op) {
1024   if (!llvm::PointerType::isValidElementType(op.getType().getUnderlyingType()))
1025     return op.emitOpError(
1026         "expects type to be a valid element type for an LLVM pointer");
1027   if (op.getParentOp() && !satisfiesLLVMModule(op.getParentOp()))
1028     return op.emitOpError("must appear at the module level");
1029 
1030   if (auto strAttr = op.getValueOrNull().dyn_cast_or_null<StringAttr>()) {
1031     auto type = op.getType();
1032     if (!type.getUnderlyingType()->isArrayTy() ||
1033         !type.getArrayElementType().getUnderlyingType()->isIntegerTy(8) ||
1034         type.getArrayNumElements() != strAttr.getValue().size())
1035       return op.emitOpError(
1036           "requires an i8 array type of the length equal to that of the string "
1037           "attribute");
1038   }
1039 
1040   if (Block *b = op.getInitializerBlock()) {
1041     ReturnOp ret = cast<ReturnOp>(b->getTerminator());
1042     if (ret.operand_type_begin() == ret.operand_type_end())
1043       return op.emitOpError("initializer region cannot return void");
1044     if (*ret.operand_type_begin() != op.getType())
1045       return op.emitOpError("initializer region type ")
1046              << *ret.operand_type_begin() << " does not match global type "
1047              << op.getType();
1048 
1049     if (op.getValueOrNull())
1050       return op.emitOpError("cannot have both initializer value and region");
1051   }
1052   return success();
1053 }
1054 
1055 //===----------------------------------------------------------------------===//
1056 // Printing/parsing for LLVM::ShuffleVectorOp.
1057 //===----------------------------------------------------------------------===//
1058 // Expects vector to be of wrapped LLVM vector type and position to be of
1059 // wrapped LLVM i32 type.
1060 void LLVM::ShuffleVectorOp::build(Builder *b, OperationState &result, Value v1,
1061                                   Value v2, ArrayAttr mask,
1062                                   ArrayRef<NamedAttribute> attrs) {
1063   auto wrappedContainerType1 = v1.getType().cast<LLVM::LLVMType>();
1064   auto vType = LLVMType::getVectorTy(
1065       wrappedContainerType1.getVectorElementType(), mask.size());
1066   build(b, result, vType, v1, v2, mask);
1067   result.addAttributes(attrs);
1068 }
1069 
1070 static void printShuffleVectorOp(OpAsmPrinter &p, ShuffleVectorOp &op) {
1071   p << op.getOperationName() << ' ' << op.v1() << ", " << op.v2() << " "
1072     << op.mask();
1073   p.printOptionalAttrDict(op.getAttrs(), {"mask"});
1074   p << " : " << op.v1().getType() << ", " << op.v2().getType();
1075 }
1076 
1077 // <operation> ::= `llvm.shufflevector` ssa-use `, ` ssa-use
1078 //                 `[` integer-literal (`,` integer-literal)* `]`
1079 //                 attribute-dict? `:` type
1080 static ParseResult parseShuffleVectorOp(OpAsmParser &parser,
1081                                         OperationState &result) {
1082   llvm::SMLoc loc;
1083   SmallVector<NamedAttribute, 4> attrs;
1084   OpAsmParser::OperandType v1, v2;
1085   Attribute maskAttr;
1086   Type typeV1, typeV2;
1087   if (parser.getCurrentLocation(&loc) || parser.parseOperand(v1) ||
1088       parser.parseComma() || parser.parseOperand(v2) ||
1089       parser.parseAttribute(maskAttr, "mask", attrs) ||
1090       parser.parseOptionalAttrDict(attrs) || parser.parseColonType(typeV1) ||
1091       parser.parseComma() || parser.parseType(typeV2) ||
1092       parser.resolveOperand(v1, typeV1, result.operands) ||
1093       parser.resolveOperand(v2, typeV2, result.operands))
1094     return failure();
1095   auto wrappedContainerType1 = typeV1.dyn_cast<LLVM::LLVMType>();
1096   if (!wrappedContainerType1 ||
1097       !wrappedContainerType1.getUnderlyingType()->isVectorTy())
1098     return parser.emitError(
1099         loc, "expected LLVM IR dialect vector type for operand #1");
1100   auto vType =
1101       LLVMType::getVectorTy(wrappedContainerType1.getVectorElementType(),
1102                             maskAttr.cast<ArrayAttr>().size());
1103   result.attributes = attrs;
1104   result.addTypes(vType);
1105   return success();
1106 }
1107 
1108 //===----------------------------------------------------------------------===//
1109 // Implementations for LLVM::LLVMFuncOp.
1110 //===----------------------------------------------------------------------===//
1111 
1112 // Add the entry block to the function.
1113 Block *LLVMFuncOp::addEntryBlock() {
1114   assert(empty() && "function already has an entry block");
1115   assert(!isVarArg() && "unimplemented: non-external variadic functions");
1116 
1117   auto *entry = new Block;
1118   push_back(entry);
1119 
1120   LLVMType type = getType();
1121   for (unsigned i = 0, e = type.getFunctionNumParams(); i < e; ++i)
1122     entry->addArgument(type.getFunctionParamType(i));
1123   return entry;
1124 }
1125 
1126 void LLVMFuncOp::build(Builder *builder, OperationState &result, StringRef name,
1127                        LLVMType type, LLVM::Linkage linkage,
1128                        ArrayRef<NamedAttribute> attrs,
1129                        ArrayRef<NamedAttributeList> argAttrs) {
1130   result.addRegion();
1131   result.addAttribute(SymbolTable::getSymbolAttrName(),
1132                       builder->getStringAttr(name));
1133   result.addAttribute("type", TypeAttr::get(type));
1134   result.addAttribute(getLinkageAttrName(), builder->getI64IntegerAttr(
1135                                                 static_cast<int64_t>(linkage)));
1136   result.attributes.append(attrs.begin(), attrs.end());
1137   if (argAttrs.empty())
1138     return;
1139 
1140   unsigned numInputs = type.getUnderlyingType()->getFunctionNumParams();
1141   assert(numInputs == argAttrs.size() &&
1142          "expected as many argument attribute lists as arguments");
1143   SmallString<8> argAttrName;
1144   for (unsigned i = 0; i < numInputs; ++i)
1145     if (auto argDict = argAttrs[i].getDictionary())
1146       result.addAttribute(getArgAttrName(i, argAttrName), argDict);
1147 }
1148 
1149 // Builds an LLVM function type from the given lists of input and output types.
1150 // Returns a null type if any of the types provided are non-LLVM types, or if
1151 // there is more than one output type.
1152 static Type buildLLVMFunctionType(OpAsmParser &parser, llvm::SMLoc loc,
1153                                   ArrayRef<Type> inputs, ArrayRef<Type> outputs,
1154                                   impl::VariadicFlag variadicFlag) {
1155   Builder &b = parser.getBuilder();
1156   if (outputs.size() > 1) {
1157     parser.emitError(loc, "failed to construct function type: expected zero or "
1158                           "one function result");
1159     return {};
1160   }
1161 
1162   // Convert inputs to LLVM types, exit early on error.
1163   SmallVector<LLVMType, 4> llvmInputs;
1164   for (auto t : inputs) {
1165     auto llvmTy = t.dyn_cast<LLVMType>();
1166     if (!llvmTy) {
1167       parser.emitError(loc, "failed to construct function type: expected LLVM "
1168                             "type for function arguments");
1169       return {};
1170     }
1171     llvmInputs.push_back(llvmTy);
1172   }
1173 
1174   // Get the dialect from the input type, if any exist.  Look it up in the
1175   // context otherwise.
1176   LLVMDialect *dialect =
1177       llvmInputs.empty() ? b.getContext()->getRegisteredDialect<LLVMDialect>()
1178                          : &llvmInputs.front().getDialect();
1179 
1180   // No output is denoted as "void" in LLVM type system.
1181   LLVMType llvmOutput = outputs.empty() ? LLVMType::getVoidTy(dialect)
1182                                         : outputs.front().dyn_cast<LLVMType>();
1183   if (!llvmOutput) {
1184     parser.emitError(loc, "failed to construct function type: expected LLVM "
1185                           "type for function results");
1186     return {};
1187   }
1188   return LLVMType::getFunctionTy(llvmOutput, llvmInputs,
1189                                  variadicFlag.isVariadic());
1190 }
1191 
1192 // Parses an LLVM function.
1193 //
1194 // operation ::= `llvm.func` linkage? function-signature function-attributes?
1195 //               function-body
1196 //
1197 static ParseResult parseLLVMFuncOp(OpAsmParser &parser,
1198                                    OperationState &result) {
1199   // Default to external linkage if no keyword is provided.
1200   if (failed(parseOptionalLinkageKeyword(parser, result)))
1201     result.addAttribute(getLinkageAttrName(),
1202                         parser.getBuilder().getI64IntegerAttr(
1203                             static_cast<int64_t>(LLVM::Linkage::External)));
1204 
1205   StringAttr nameAttr;
1206   SmallVector<OpAsmParser::OperandType, 8> entryArgs;
1207   SmallVector<SmallVector<NamedAttribute, 2>, 1> argAttrs;
1208   SmallVector<SmallVector<NamedAttribute, 2>, 1> resultAttrs;
1209   SmallVector<Type, 8> argTypes;
1210   SmallVector<Type, 4> resultTypes;
1211   bool isVariadic;
1212 
1213   auto signatureLocation = parser.getCurrentLocation();
1214   if (parser.parseSymbolName(nameAttr, SymbolTable::getSymbolAttrName(),
1215                              result.attributes) ||
1216       impl::parseFunctionSignature(parser, /*allowVariadic=*/true, entryArgs,
1217                                    argTypes, argAttrs, isVariadic, resultTypes,
1218                                    resultAttrs))
1219     return failure();
1220 
1221   auto type =
1222       buildLLVMFunctionType(parser, signatureLocation, argTypes, resultTypes,
1223                             impl::VariadicFlag(isVariadic));
1224   if (!type)
1225     return failure();
1226   result.addAttribute(impl::getTypeAttrName(), TypeAttr::get(type));
1227 
1228   if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes)))
1229     return failure();
1230   impl::addArgAndResultAttrs(parser.getBuilder(), result, argAttrs,
1231                              resultAttrs);
1232 
1233   auto *body = result.addRegion();
1234   return parser.parseOptionalRegion(
1235       *body, entryArgs, entryArgs.empty() ? ArrayRef<Type>() : argTypes);
1236 }
1237 
1238 // Print the LLVMFuncOp. Collects argument and result types and passes them to
1239 // helper functions. Drops "void" result since it cannot be parsed back. Skips
1240 // the external linkage since it is the default value.
1241 static void printLLVMFuncOp(OpAsmPrinter &p, LLVMFuncOp op) {
1242   p << op.getOperationName() << ' ';
1243   if (op.linkage() != LLVM::Linkage::External) {
1244     printLinkage(p, op.linkage());
1245     p << ' ';
1246   }
1247   p.printSymbolName(op.getName());
1248 
1249   LLVMType fnType = op.getType();
1250   SmallVector<Type, 8> argTypes;
1251   SmallVector<Type, 1> resTypes;
1252   argTypes.reserve(fnType.getFunctionNumParams());
1253   for (unsigned i = 0, e = fnType.getFunctionNumParams(); i < e; ++i)
1254     argTypes.push_back(fnType.getFunctionParamType(i));
1255 
1256   LLVMType returnType = fnType.getFunctionResultType();
1257   if (!returnType.getUnderlyingType()->isVoidTy())
1258     resTypes.push_back(returnType);
1259 
1260   impl::printFunctionSignature(p, op, argTypes, op.isVarArg(), resTypes);
1261   impl::printFunctionAttributes(p, op, argTypes.size(), resTypes.size(),
1262                                 {getLinkageAttrName()});
1263 
1264   // Print the body if this is not an external function.
1265   Region &body = op.body();
1266   if (!body.empty())
1267     p.printRegion(body, /*printEntryBlockArgs=*/false,
1268                   /*printBlockTerminators=*/true);
1269 }
1270 
1271 // Hook for OpTrait::FunctionLike, called after verifying that the 'type'
1272 // attribute is present.  This can check for preconditions of the
1273 // getNumArguments hook not failing.
1274 LogicalResult LLVMFuncOp::verifyType() {
1275   auto llvmType = getTypeAttr().getValue().dyn_cast_or_null<LLVMType>();
1276   if (!llvmType || !llvmType.getUnderlyingType()->isFunctionTy())
1277     return emitOpError("requires '" + getTypeAttrName() +
1278                        "' attribute of wrapped LLVM function type");
1279 
1280   return success();
1281 }
1282 
1283 // Hook for OpTrait::FunctionLike, returns the number of function arguments.
1284 // Depends on the type attribute being correct as checked by verifyType
1285 unsigned LLVMFuncOp::getNumFuncArguments() {
1286   return getType().getUnderlyingType()->getFunctionNumParams();
1287 }
1288 
1289 // Hook for OpTrait::FunctionLike, returns the number of function results.
1290 // Depends on the type attribute being correct as checked by verifyType
1291 unsigned LLVMFuncOp::getNumFuncResults() {
1292   llvm::FunctionType *funcType =
1293       cast<llvm::FunctionType>(getType().getUnderlyingType());
1294   // We model LLVM functions that return void as having zero results,
1295   // and all others as having one result.
1296   // If we modeled a void return as one result, then it would be possible to
1297   // attach an MLIR result attribute to it, and it isn't clear what semantics we
1298   // would assign to that.
1299   if (funcType->getReturnType()->isVoidTy())
1300     return 0;
1301   return 1;
1302 }
1303 
1304 // Verifies LLVM- and implementation-specific properties of the LLVM func Op:
1305 // - functions don't have 'common' linkage
1306 // - external functions have 'external' or 'extern_weak' linkage;
1307 // - vararg is (currently) only supported for external functions;
1308 // - entry block arguments are of LLVM types and match the function signature.
1309 static LogicalResult verify(LLVMFuncOp op) {
1310   if (op.linkage() == LLVM::Linkage::Common)
1311     return op.emitOpError()
1312            << "functions cannot have '" << linkageToStr(LLVM::Linkage::Common)
1313            << "' linkage";
1314 
1315   if (op.isExternal()) {
1316     if (op.linkage() != LLVM::Linkage::External &&
1317         op.linkage() != LLVM::Linkage::ExternWeak)
1318       return op.emitOpError()
1319              << "external functions must have '"
1320              << linkageToStr(LLVM::Linkage::External) << "' or '"
1321              << linkageToStr(LLVM::Linkage::ExternWeak) << "' linkage";
1322     return success();
1323   }
1324 
1325   if (op.isVarArg())
1326     return op.emitOpError("only external functions can be variadic");
1327 
1328   auto *funcType = cast<llvm::FunctionType>(op.getType().getUnderlyingType());
1329   unsigned numArguments = funcType->getNumParams();
1330   Block &entryBlock = op.front();
1331   for (unsigned i = 0; i < numArguments; ++i) {
1332     Type argType = entryBlock.getArgument(i).getType();
1333     auto argLLVMType = argType.dyn_cast<LLVMType>();
1334     if (!argLLVMType)
1335       return op.emitOpError("entry block argument #")
1336              << i << " is not of LLVM type";
1337     if (funcType->getParamType(i) != argLLVMType.getUnderlyingType())
1338       return op.emitOpError("the type of entry block argument #")
1339              << i << " does not match the function signature";
1340   }
1341 
1342   return success();
1343 }
1344 
1345 //===----------------------------------------------------------------------===//
1346 // Printing, parsing and verification for LLVM::NullOp.
1347 //===----------------------------------------------------------------------===//
1348 
1349 static void printNullOp(OpAsmPrinter &p, LLVM::NullOp op) {
1350   p << NullOp::getOperationName();
1351   p.printOptionalAttrDict(op.getAttrs());
1352   p << " : " << op.getType();
1353 }
1354 
1355 // <operation> = `llvm.mlir.null` : type
1356 static ParseResult parseNullOp(OpAsmParser &parser, OperationState &result) {
1357   Type type;
1358   return failure(parser.parseOptionalAttrDict(result.attributes) ||
1359                  parser.parseColonType(type) ||
1360                  parser.addTypeToList(type, result.types));
1361 }
1362 
1363 // Only LLVM pointer types are supported.
1364 static LogicalResult verify(LLVM::NullOp op) {
1365   auto llvmType = op.getType().dyn_cast<LLVM::LLVMType>();
1366   if (!llvmType || !llvmType.isPointerTy())
1367     return op.emitOpError("expected LLVM IR pointer type");
1368   return success();
1369 }
1370 
1371 //===----------------------------------------------------------------------===//
1372 // LLVMDialect initialization, type parsing, and registration.
1373 //===----------------------------------------------------------------------===//
1374 
1375 namespace mlir {
1376 namespace LLVM {
1377 namespace detail {
1378 struct LLVMDialectImpl {
1379   LLVMDialectImpl() : module("LLVMDialectModule", llvmContext) {}
1380 
1381   llvm::LLVMContext llvmContext;
1382   llvm::Module module;
1383 
1384   /// A set of LLVMTypes that are cached on construction to avoid any lookups or
1385   /// locking.
1386   LLVMType int1Ty, int8Ty, int16Ty, int32Ty, int64Ty, int128Ty;
1387   LLVMType doubleTy, floatTy, halfTy, fp128Ty, x86_fp80Ty;
1388   LLVMType voidTy;
1389 
1390   /// A smart mutex to lock access to the llvm context. Unlike MLIR, LLVM is not
1391   /// multi-threaded and requires locked access to prevent race conditions.
1392   llvm::sys::SmartMutex<true> mutex;
1393 };
1394 } // end namespace detail
1395 } // end namespace LLVM
1396 } // end namespace mlir
1397 
1398 LLVMDialect::LLVMDialect(MLIRContext *context)
1399     : Dialect(getDialectNamespace(), context),
1400       impl(new detail::LLVMDialectImpl()) {
1401   addTypes<LLVMType>();
1402   addOperations<
1403 #define GET_OP_LIST
1404 #include "mlir/Dialect/LLVMIR/LLVMOps.cpp.inc"
1405       >();
1406 
1407   // Support unknown operations because not all LLVM operations are registered.
1408   allowUnknownOperations();
1409 
1410   // Cache some of the common LLVM types to avoid the need for lookups/locking.
1411   auto &llvmContext = impl->llvmContext;
1412   /// Integer Types.
1413   impl->int1Ty = LLVMType::get(context, llvm::Type::getInt1Ty(llvmContext));
1414   impl->int8Ty = LLVMType::get(context, llvm::Type::getInt8Ty(llvmContext));
1415   impl->int16Ty = LLVMType::get(context, llvm::Type::getInt16Ty(llvmContext));
1416   impl->int32Ty = LLVMType::get(context, llvm::Type::getInt32Ty(llvmContext));
1417   impl->int64Ty = LLVMType::get(context, llvm::Type::getInt64Ty(llvmContext));
1418   impl->int128Ty = LLVMType::get(context, llvm::Type::getInt128Ty(llvmContext));
1419   /// Float Types.
1420   impl->doubleTy = LLVMType::get(context, llvm::Type::getDoubleTy(llvmContext));
1421   impl->floatTy = LLVMType::get(context, llvm::Type::getFloatTy(llvmContext));
1422   impl->halfTy = LLVMType::get(context, llvm::Type::getHalfTy(llvmContext));
1423   impl->fp128Ty = LLVMType::get(context, llvm::Type::getFP128Ty(llvmContext));
1424   impl->x86_fp80Ty =
1425       LLVMType::get(context, llvm::Type::getX86_FP80Ty(llvmContext));
1426   /// Other Types.
1427   impl->voidTy = LLVMType::get(context, llvm::Type::getVoidTy(llvmContext));
1428 }
1429 
1430 LLVMDialect::~LLVMDialect() {}
1431 
1432 #define GET_OP_CLASSES
1433 #include "mlir/Dialect/LLVMIR/LLVMOps.cpp.inc"
1434 
1435 llvm::LLVMContext &LLVMDialect::getLLVMContext() { return impl->llvmContext; }
1436 llvm::Module &LLVMDialect::getLLVMModule() { return impl->module; }
1437 
1438 /// Parse a type registered to this dialect.
1439 Type LLVMDialect::parseType(DialectAsmParser &parser) const {
1440   StringRef tyData = parser.getFullSymbolSpec();
1441 
1442   // LLVM is not thread-safe, so lock access to it.
1443   llvm::sys::SmartScopedLock<true> lock(impl->mutex);
1444 
1445   llvm::SMDiagnostic errorMessage;
1446   llvm::Type *type = llvm::parseType(tyData, errorMessage, impl->module);
1447   if (!type)
1448     return (parser.emitError(parser.getNameLoc(), errorMessage.getMessage()),
1449             nullptr);
1450   return LLVMType::get(getContext(), type);
1451 }
1452 
1453 /// Print a type registered to this dialect.
1454 void LLVMDialect::printType(Type type, DialectAsmPrinter &os) const {
1455   auto llvmType = type.dyn_cast<LLVMType>();
1456   assert(llvmType && "printing wrong type");
1457   assert(llvmType.getUnderlyingType() && "no underlying LLVM type");
1458   llvmType.getUnderlyingType()->print(os.getStream());
1459 }
1460 
1461 /// Verify LLVMIR function argument attributes.
1462 LogicalResult LLVMDialect::verifyRegionArgAttribute(Operation *op,
1463                                                     unsigned regionIdx,
1464                                                     unsigned argIdx,
1465                                                     NamedAttribute argAttr) {
1466   // Check that llvm.noalias is a boolean attribute.
1467   if (argAttr.first == "llvm.noalias" && !argAttr.second.isa<BoolAttr>())
1468     return op->emitError()
1469            << "llvm.noalias argument attribute of non boolean type";
1470   return success();
1471 }
1472 
1473 static DialectRegistration<LLVMDialect> llvmDialect;
1474 
1475 //===----------------------------------------------------------------------===//
1476 // LLVMType.
1477 //===----------------------------------------------------------------------===//
1478 
1479 namespace mlir {
1480 namespace LLVM {
1481 namespace detail {
1482 struct LLVMTypeStorage : public ::mlir::TypeStorage {
1483   LLVMTypeStorage(llvm::Type *ty) : underlyingType(ty) {}
1484 
1485   // LLVM types are pointer-unique.
1486   using KeyTy = llvm::Type *;
1487   bool operator==(const KeyTy &key) const { return key == underlyingType; }
1488 
1489   static LLVMTypeStorage *construct(TypeStorageAllocator &allocator,
1490                                     llvm::Type *ty) {
1491     return new (allocator.allocate<LLVMTypeStorage>()) LLVMTypeStorage(ty);
1492   }
1493 
1494   llvm::Type *underlyingType;
1495 };
1496 } // end namespace detail
1497 } // end namespace LLVM
1498 } // end namespace mlir
1499 
1500 LLVMType LLVMType::get(MLIRContext *context, llvm::Type *llvmType) {
1501   return Base::get(context, FIRST_LLVM_TYPE, llvmType);
1502 }
1503 
1504 /// Get an LLVMType with an llvm type that may cause changes to the underlying
1505 /// llvm context when constructed.
1506 LLVMType LLVMType::getLocked(LLVMDialect *dialect,
1507                              function_ref<llvm::Type *()> typeBuilder) {
1508   // Lock access to the llvm context and build the type.
1509   llvm::sys::SmartScopedLock<true> lock(dialect->impl->mutex);
1510   return get(dialect->getContext(), typeBuilder());
1511 }
1512 
1513 LLVMDialect &LLVMType::getDialect() {
1514   return static_cast<LLVMDialect &>(Type::getDialect());
1515 }
1516 
1517 llvm::Type *LLVMType::getUnderlyingType() const {
1518   return getImpl()->underlyingType;
1519 }
1520 
1521 /// Array type utilities.
1522 LLVMType LLVMType::getArrayElementType() {
1523   return get(getContext(), getUnderlyingType()->getArrayElementType());
1524 }
1525 unsigned LLVMType::getArrayNumElements() {
1526   return getUnderlyingType()->getArrayNumElements();
1527 }
1528 bool LLVMType::isArrayTy() { return getUnderlyingType()->isArrayTy(); }
1529 
1530 /// Vector type utilities.
1531 LLVMType LLVMType::getVectorElementType() {
1532   return get(getContext(), getUnderlyingType()->getVectorElementType());
1533 }
1534 bool LLVMType::isVectorTy() { return getUnderlyingType()->isVectorTy(); }
1535 
1536 /// Function type utilities.
1537 LLVMType LLVMType::getFunctionParamType(unsigned argIdx) {
1538   return get(getContext(), getUnderlyingType()->getFunctionParamType(argIdx));
1539 }
1540 unsigned LLVMType::getFunctionNumParams() {
1541   return getUnderlyingType()->getFunctionNumParams();
1542 }
1543 LLVMType LLVMType::getFunctionResultType() {
1544   return get(
1545       getContext(),
1546       llvm::cast<llvm::FunctionType>(getUnderlyingType())->getReturnType());
1547 }
1548 bool LLVMType::isFunctionTy() { return getUnderlyingType()->isFunctionTy(); }
1549 
1550 /// Pointer type utilities.
1551 LLVMType LLVMType::getPointerTo(unsigned addrSpace) {
1552   // Lock access to the dialect as this may modify the LLVM context.
1553   return getLocked(&getDialect(), [=] {
1554     return getUnderlyingType()->getPointerTo(addrSpace);
1555   });
1556 }
1557 LLVMType LLVMType::getPointerElementTy() {
1558   return get(getContext(), getUnderlyingType()->getPointerElementType());
1559 }
1560 bool LLVMType::isPointerTy() { return getUnderlyingType()->isPointerTy(); }
1561 
1562 /// Struct type utilities.
1563 LLVMType LLVMType::getStructElementType(unsigned i) {
1564   return get(getContext(), getUnderlyingType()->getStructElementType(i));
1565 }
1566 unsigned LLVMType::getStructNumElements() {
1567   return getUnderlyingType()->getStructNumElements();
1568 }
1569 bool LLVMType::isStructTy() { return getUnderlyingType()->isStructTy(); }
1570 
1571 /// Utilities used to generate floating point types.
1572 LLVMType LLVMType::getDoubleTy(LLVMDialect *dialect) {
1573   return dialect->impl->doubleTy;
1574 }
1575 LLVMType LLVMType::getFloatTy(LLVMDialect *dialect) {
1576   return dialect->impl->floatTy;
1577 }
1578 LLVMType LLVMType::getHalfTy(LLVMDialect *dialect) {
1579   return dialect->impl->halfTy;
1580 }
1581 LLVMType LLVMType::getFP128Ty(LLVMDialect *dialect) {
1582   return dialect->impl->fp128Ty;
1583 }
1584 LLVMType LLVMType::getX86_FP80Ty(LLVMDialect *dialect) {
1585   return dialect->impl->x86_fp80Ty;
1586 }
1587 
1588 /// Utilities used to generate integer types.
1589 LLVMType LLVMType::getIntNTy(LLVMDialect *dialect, unsigned numBits) {
1590   switch (numBits) {
1591   case 1:
1592     return dialect->impl->int1Ty;
1593   case 8:
1594     return dialect->impl->int8Ty;
1595   case 16:
1596     return dialect->impl->int16Ty;
1597   case 32:
1598     return dialect->impl->int32Ty;
1599   case 64:
1600     return dialect->impl->int64Ty;
1601   case 128:
1602     return dialect->impl->int128Ty;
1603   default:
1604     break;
1605   }
1606 
1607   // Lock access to the dialect as this may modify the LLVM context.
1608   return getLocked(dialect, [=] {
1609     return llvm::Type::getIntNTy(dialect->getLLVMContext(), numBits);
1610   });
1611 }
1612 
1613 /// Utilities used to generate other miscellaneous types.
1614 LLVMType LLVMType::getArrayTy(LLVMType elementType, uint64_t numElements) {
1615   // Lock access to the dialect as this may modify the LLVM context.
1616   return getLocked(&elementType.getDialect(), [=] {
1617     return llvm::ArrayType::get(elementType.getUnderlyingType(), numElements);
1618   });
1619 }
1620 LLVMType LLVMType::getFunctionTy(LLVMType result, ArrayRef<LLVMType> params,
1621                                  bool isVarArg) {
1622   SmallVector<llvm::Type *, 8> llvmParams;
1623   for (auto param : params)
1624     llvmParams.push_back(param.getUnderlyingType());
1625 
1626   // Lock access to the dialect as this may modify the LLVM context.
1627   return getLocked(&result.getDialect(), [=] {
1628     return llvm::FunctionType::get(result.getUnderlyingType(), llvmParams,
1629                                    isVarArg);
1630   });
1631 }
1632 LLVMType LLVMType::getStructTy(LLVMDialect *dialect,
1633                                ArrayRef<LLVMType> elements, bool isPacked) {
1634   SmallVector<llvm::Type *, 8> llvmElements;
1635   for (auto elt : elements)
1636     llvmElements.push_back(elt.getUnderlyingType());
1637 
1638   // Lock access to the dialect as this may modify the LLVM context.
1639   return getLocked(dialect, [=] {
1640     return llvm::StructType::get(dialect->getLLVMContext(), llvmElements,
1641                                  isPacked);
1642   });
1643 }
1644 LLVMType LLVMType::getVectorTy(LLVMType elementType, unsigned numElements) {
1645   // Lock access to the dialect as this may modify the LLVM context.
1646   return getLocked(&elementType.getDialect(), [=] {
1647     return llvm::VectorType::get(elementType.getUnderlyingType(), numElements);
1648   });
1649 }
1650 LLVMType LLVMType::getVoidTy(LLVMDialect *dialect) {
1651   return dialect->impl->voidTy;
1652 }
1653 
1654 //===----------------------------------------------------------------------===//
1655 // Utility functions.
1656 //===----------------------------------------------------------------------===//
1657 
1658 Value mlir::LLVM::createGlobalString(Location loc, OpBuilder &builder,
1659                                      StringRef name, StringRef value,
1660                                      LLVM::Linkage linkage,
1661                                      LLVM::LLVMDialect *llvmDialect) {
1662   assert(builder.getInsertionBlock() &&
1663          builder.getInsertionBlock()->getParentOp() &&
1664          "expected builder to point to a block constrained in an op");
1665   auto module =
1666       builder.getInsertionBlock()->getParentOp()->getParentOfType<ModuleOp>();
1667   assert(module && "builder points to an op outside of a module");
1668 
1669   // Create the global at the entry of the module.
1670   OpBuilder moduleBuilder(module.getBodyRegion());
1671   auto type = LLVM::LLVMType::getArrayTy(LLVM::LLVMType::getInt8Ty(llvmDialect),
1672                                          value.size());
1673   auto global = moduleBuilder.create<LLVM::GlobalOp>(
1674       loc, type, /*isConstant=*/true, linkage, name,
1675       builder.getStringAttr(value));
1676 
1677   // Get the pointer to the first character in the global string.
1678   Value globalPtr = builder.create<LLVM::AddressOfOp>(loc, global);
1679   Value cst0 = builder.create<LLVM::ConstantOp>(
1680       loc, LLVM::LLVMType::getInt64Ty(llvmDialect),
1681       builder.getIntegerAttr(builder.getIndexType(), 0));
1682   return builder.create<LLVM::GEPOp>(loc,
1683                                      LLVM::LLVMType::getInt8PtrTy(llvmDialect),
1684                                      globalPtr, ArrayRef<Value>({cst0, cst0}));
1685 }
1686 
1687 bool mlir::LLVM::satisfiesLLVMModule(Operation *op) {
1688   return op->hasTrait<OpTrait::SymbolTable>() &&
1689          op->hasTrait<OpTrait::IsIsolatedFromAbove>();
1690 }
1691