MLIR  14.0.0git
LLVMToLLVMIRTranslation.cpp
Go to the documentation of this file.
1 //===- LLVMToLLVMIRTranslation.cpp - Translate LLVM dialect to LLVM IR ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements a translation between the MLIR LLVM dialect and LLVM IR.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 #include "mlir/IR/Operation.h"
16 #include "mlir/Support/LLVM.h"
18 
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/InlineAsm.h"
21 #include "llvm/IR/MDBuilder.h"
22 #include "llvm/IR/MatrixBuilder.h"
23 #include "llvm/IR/Operator.h"
24 
25 using namespace mlir;
26 using namespace mlir::LLVM;
28 
29 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
30 
31 /// Convert MLIR integer comparison predicate to LLVM IR comparison predicate.
32 static llvm::CmpInst::Predicate getLLVMCmpPredicate(ICmpPredicate p) {
33  switch (p) {
34  case LLVM::ICmpPredicate::eq:
35  return llvm::CmpInst::Predicate::ICMP_EQ;
36  case LLVM::ICmpPredicate::ne:
37  return llvm::CmpInst::Predicate::ICMP_NE;
38  case LLVM::ICmpPredicate::slt:
39  return llvm::CmpInst::Predicate::ICMP_SLT;
40  case LLVM::ICmpPredicate::sle:
41  return llvm::CmpInst::Predicate::ICMP_SLE;
42  case LLVM::ICmpPredicate::sgt:
43  return llvm::CmpInst::Predicate::ICMP_SGT;
44  case LLVM::ICmpPredicate::sge:
45  return llvm::CmpInst::Predicate::ICMP_SGE;
46  case LLVM::ICmpPredicate::ult:
47  return llvm::CmpInst::Predicate::ICMP_ULT;
48  case LLVM::ICmpPredicate::ule:
49  return llvm::CmpInst::Predicate::ICMP_ULE;
50  case LLVM::ICmpPredicate::ugt:
51  return llvm::CmpInst::Predicate::ICMP_UGT;
52  case LLVM::ICmpPredicate::uge:
53  return llvm::CmpInst::Predicate::ICMP_UGE;
54  }
55  llvm_unreachable("incorrect comparison predicate");
56 }
57 
58 static llvm::CmpInst::Predicate getLLVMCmpPredicate(FCmpPredicate p) {
59  switch (p) {
60  case LLVM::FCmpPredicate::_false:
61  return llvm::CmpInst::Predicate::FCMP_FALSE;
62  case LLVM::FCmpPredicate::oeq:
63  return llvm::CmpInst::Predicate::FCMP_OEQ;
64  case LLVM::FCmpPredicate::ogt:
65  return llvm::CmpInst::Predicate::FCMP_OGT;
66  case LLVM::FCmpPredicate::oge:
67  return llvm::CmpInst::Predicate::FCMP_OGE;
68  case LLVM::FCmpPredicate::olt:
69  return llvm::CmpInst::Predicate::FCMP_OLT;
70  case LLVM::FCmpPredicate::ole:
71  return llvm::CmpInst::Predicate::FCMP_OLE;
72  case LLVM::FCmpPredicate::one:
73  return llvm::CmpInst::Predicate::FCMP_ONE;
74  case LLVM::FCmpPredicate::ord:
75  return llvm::CmpInst::Predicate::FCMP_ORD;
76  case LLVM::FCmpPredicate::ueq:
77  return llvm::CmpInst::Predicate::FCMP_UEQ;
78  case LLVM::FCmpPredicate::ugt:
79  return llvm::CmpInst::Predicate::FCMP_UGT;
80  case LLVM::FCmpPredicate::uge:
81  return llvm::CmpInst::Predicate::FCMP_UGE;
82  case LLVM::FCmpPredicate::ult:
83  return llvm::CmpInst::Predicate::FCMP_ULT;
84  case LLVM::FCmpPredicate::ule:
85  return llvm::CmpInst::Predicate::FCMP_ULE;
86  case LLVM::FCmpPredicate::une:
87  return llvm::CmpInst::Predicate::FCMP_UNE;
88  case LLVM::FCmpPredicate::uno:
89  return llvm::CmpInst::Predicate::FCMP_UNO;
90  case LLVM::FCmpPredicate::_true:
91  return llvm::CmpInst::Predicate::FCMP_TRUE;
92  }
93  llvm_unreachable("incorrect comparison predicate");
94 }
95 
96 static llvm::AtomicRMWInst::BinOp getLLVMAtomicBinOp(AtomicBinOp op) {
97  switch (op) {
98  case LLVM::AtomicBinOp::xchg:
99  return llvm::AtomicRMWInst::BinOp::Xchg;
100  case LLVM::AtomicBinOp::add:
101  return llvm::AtomicRMWInst::BinOp::Add;
102  case LLVM::AtomicBinOp::sub:
103  return llvm::AtomicRMWInst::BinOp::Sub;
104  case LLVM::AtomicBinOp::_and:
105  return llvm::AtomicRMWInst::BinOp::And;
106  case LLVM::AtomicBinOp::nand:
107  return llvm::AtomicRMWInst::BinOp::Nand;
108  case LLVM::AtomicBinOp::_or:
109  return llvm::AtomicRMWInst::BinOp::Or;
110  case LLVM::AtomicBinOp::_xor:
111  return llvm::AtomicRMWInst::BinOp::Xor;
113  return llvm::AtomicRMWInst::BinOp::Max;
115  return llvm::AtomicRMWInst::BinOp::Min;
116  case LLVM::AtomicBinOp::umax:
117  return llvm::AtomicRMWInst::BinOp::UMax;
118  case LLVM::AtomicBinOp::umin:
119  return llvm::AtomicRMWInst::BinOp::UMin;
120  case LLVM::AtomicBinOp::fadd:
121  return llvm::AtomicRMWInst::BinOp::FAdd;
122  case LLVM::AtomicBinOp::fsub:
123  return llvm::AtomicRMWInst::BinOp::FSub;
124  }
125  llvm_unreachable("incorrect atomic binary operator");
126 }
127 
128 static llvm::AtomicOrdering getLLVMAtomicOrdering(AtomicOrdering ordering) {
129  switch (ordering) {
130  case LLVM::AtomicOrdering::not_atomic:
131  return llvm::AtomicOrdering::NotAtomic;
132  case LLVM::AtomicOrdering::unordered:
133  return llvm::AtomicOrdering::Unordered;
134  case LLVM::AtomicOrdering::monotonic:
135  return llvm::AtomicOrdering::Monotonic;
136  case LLVM::AtomicOrdering::acquire:
137  return llvm::AtomicOrdering::Acquire;
138  case LLVM::AtomicOrdering::release:
139  return llvm::AtomicOrdering::Release;
140  case LLVM::AtomicOrdering::acq_rel:
141  return llvm::AtomicOrdering::AcquireRelease;
142  case LLVM::AtomicOrdering::seq_cst:
143  return llvm::AtomicOrdering::SequentiallyConsistent;
144  }
145  llvm_unreachable("incorrect atomic ordering");
146 }
147 
148 static llvm::FastMathFlags getFastmathFlags(FastmathFlagsInterface &op) {
149  using llvmFMF = llvm::FastMathFlags;
150  using FuncT = void (llvmFMF::*)(bool);
151  const std::pair<FastmathFlags, FuncT> handlers[] = {
152  // clang-format off
153  {FastmathFlags::nnan, &llvmFMF::setNoNaNs},
154  {FastmathFlags::ninf, &llvmFMF::setNoInfs},
155  {FastmathFlags::nsz, &llvmFMF::setNoSignedZeros},
156  {FastmathFlags::arcp, &llvmFMF::setAllowReciprocal},
157  {FastmathFlags::contract, &llvmFMF::setAllowContract},
158  {FastmathFlags::afn, &llvmFMF::setApproxFunc},
159  {FastmathFlags::reassoc, &llvmFMF::setAllowReassoc},
160  {FastmathFlags::fast, &llvmFMF::setFast},
161  // clang-format on
162  };
163  llvm::FastMathFlags ret;
164  auto fmf = op.fastmathFlags();
165  for (auto it : handlers)
166  if (bitEnumContains(fmf, it.first))
167  (ret.*(it.second))(true);
168  return ret;
169 }
170 
171 /// Returns an LLVM metadata node corresponding to a loop option. This metadata
172 /// is attached to an llvm.loop node.
173 static llvm::MDNode *getLoopOptionMetadata(llvm::LLVMContext &ctx,
174  LoopOptionCase option,
175  int64_t value) {
176  StringRef name;
177  llvm::Constant *cstValue = nullptr;
178  switch (option) {
179  case LoopOptionCase::disable_licm:
180  name = "llvm.licm.disable";
181  cstValue = llvm::ConstantInt::getBool(ctx, value);
182  break;
183  case LoopOptionCase::disable_unroll:
184  name = "llvm.loop.unroll.disable";
185  cstValue = llvm::ConstantInt::getBool(ctx, value);
186  break;
187  case LoopOptionCase::interleave_count:
188  name = "llvm.loop.interleave.count";
189  cstValue = llvm::ConstantInt::get(
190  llvm::IntegerType::get(ctx, /*NumBits=*/32), value);
191  break;
192  case LoopOptionCase::disable_pipeline:
193  name = "llvm.loop.pipeline.disable";
194  cstValue = llvm::ConstantInt::getBool(ctx, value);
195  break;
196  case LoopOptionCase::pipeline_initiation_interval:
197  name = "llvm.loop.pipeline.initiationinterval";
198  cstValue = llvm::ConstantInt::get(
199  llvm::IntegerType::get(ctx, /*NumBits=*/32), value);
200  break;
201  }
202  return llvm::MDNode::get(ctx, {llvm::MDString::get(ctx, name),
203  llvm::ConstantAsMetadata::get(cstValue)});
204 }
205 
206 static void setLoopMetadata(Operation &opInst, llvm::Instruction &llvmInst,
207  llvm::IRBuilderBase &builder,
208  LLVM::ModuleTranslation &moduleTranslation) {
209  if (Attribute attr = opInst.getAttr(LLVMDialect::getLoopAttrName())) {
210  llvm::Module *module = builder.GetInsertBlock()->getModule();
211  llvm::MDNode *loopMD = moduleTranslation.lookupLoopOptionsMetadata(attr);
212  if (!loopMD) {
213  llvm::LLVMContext &ctx = module->getContext();
214 
215  SmallVector<llvm::Metadata *> loopOptions;
216  // Reserve operand 0 for loop id self reference.
217  auto dummy = llvm::MDNode::getTemporary(ctx, llvm::None);
218  loopOptions.push_back(dummy.get());
219 
220  auto loopAttr = attr.cast<DictionaryAttr>();
221  auto parallelAccessGroup =
222  loopAttr.getNamed(LLVMDialect::getParallelAccessAttrName());
223  if (parallelAccessGroup.hasValue()) {
224  SmallVector<llvm::Metadata *> parallelAccess;
225  parallelAccess.push_back(
226  llvm::MDString::get(ctx, "llvm.loop.parallel_accesses"));
227  for (SymbolRefAttr accessGroupRef : parallelAccessGroup->getValue()
228  .cast<ArrayAttr>()
229  .getAsRange<SymbolRefAttr>())
230  parallelAccess.push_back(
231  moduleTranslation.getAccessGroup(opInst, accessGroupRef));
232  loopOptions.push_back(llvm::MDNode::get(ctx, parallelAccess));
233  }
234 
235  if (auto loopOptionsAttr = loopAttr.getAs<LoopOptionsAttr>(
236  LLVMDialect::getLoopOptionsAttrName())) {
237  for (auto option : loopOptionsAttr.getOptions())
238  loopOptions.push_back(
239  getLoopOptionMetadata(ctx, option.first, option.second));
240  }
241 
242  // Create loop options and set the first operand to itself.
243  loopMD = llvm::MDNode::get(ctx, loopOptions);
244  loopMD->replaceOperandWith(0, loopMD);
245 
246  // Store a map from this Attribute to the LLVM metadata in case we
247  // encounter it again.
248  moduleTranslation.mapLoopOptionsMetadata(attr, loopMD);
249  }
250 
251  llvmInst.setMetadata(module->getMDKindID("llvm.loop"), loopMD);
252  }
253 }
254 
255 static LogicalResult
256 convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
257  LLVM::ModuleTranslation &moduleTranslation) {
258  auto extractPosition = [](ArrayAttr attr) {
259  SmallVector<unsigned, 4> position;
260  position.reserve(attr.size());
261  for (Attribute v : attr)
262  position.push_back(v.cast<IntegerAttr>().getValue().getZExtValue());
263  return position;
264  };
265 
266  llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
267  if (auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
268  builder.setFastMathFlags(getFastmathFlags(fmf));
269 
270 #include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
271 
272  // Emit function calls. If the "callee" attribute is present, this is a
273  // direct function call and we also need to look up the remapped function
274  // itself. Otherwise, this is an indirect call and the callee is the first
275  // operand, look it up as a normal value. Return the llvm::Value representing
276  // the function result, which may be of llvm::VoidTy type.
277  auto convertCall = [&](Operation &op) -> llvm::Value * {
278  auto operands = moduleTranslation.lookupValues(op.getOperands());
279  ArrayRef<llvm::Value *> operandsRef(operands);
280  if (auto attr = op.getAttrOfType<FlatSymbolRefAttr>("callee"))
281  return builder.CreateCall(
282  moduleTranslation.lookupFunction(attr.getValue()), operandsRef);
283  auto *calleePtrType =
284  cast<llvm::PointerType>(operandsRef.front()->getType());
285  auto *calleeType =
286  cast<llvm::FunctionType>(calleePtrType->getElementType());
287  return builder.CreateCall(calleeType, operandsRef.front(),
288  operandsRef.drop_front());
289  };
290 
291  // Emit calls. If the called function has a result, remap the corresponding
292  // value. Note that LLVM IR dialect CallOp has either 0 or 1 result.
293  if (isa<LLVM::CallOp>(opInst)) {
294  llvm::Value *result = convertCall(opInst);
295  if (opInst.getNumResults() != 0) {
296  moduleTranslation.mapValue(opInst.getResult(0), result);
297  return success();
298  }
299  // Check that LLVM call returns void for 0-result functions.
300  return success(result->getType()->isVoidTy());
301  }
302 
303  if (auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
304  // TODO: refactor function type creation which usually occurs in std-LLVM
305  // conversion.
306  SmallVector<Type, 8> operandTypes;
307  operandTypes.reserve(inlineAsmOp.getOperands().size());
308  for (auto t : inlineAsmOp.getOperands().getTypes())
309  operandTypes.push_back(t);
310 
311  Type resultType;
312  if (inlineAsmOp.getNumResults() == 0) {
313  resultType = LLVM::LLVMVoidType::get(&moduleTranslation.getContext());
314  } else {
315  assert(inlineAsmOp.getNumResults() == 1);
316  resultType = inlineAsmOp.getResultTypes()[0];
317  }
318  auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
319  llvm::InlineAsm *inlineAsmInst =
320  inlineAsmOp.getAsmDialect().hasValue()
321  ? llvm::InlineAsm::get(
322  static_cast<llvm::FunctionType *>(
323  moduleTranslation.convertType(ft)),
324  inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
325  inlineAsmOp.getHasSideEffects(),
326  inlineAsmOp.getIsAlignStack(),
327  convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
328  : llvm::InlineAsm::get(static_cast<llvm::FunctionType *>(
329  moduleTranslation.convertType(ft)),
330  inlineAsmOp.getAsmString(),
331  inlineAsmOp.getConstraints(),
332  inlineAsmOp.getHasSideEffects(),
333  inlineAsmOp.getIsAlignStack());
334  llvm::Value *result = builder.CreateCall(
335  inlineAsmInst,
336  moduleTranslation.lookupValues(inlineAsmOp.getOperands()));
337  if (opInst.getNumResults() != 0)
338  moduleTranslation.mapValue(opInst.getResult(0), result);
339  return success();
340  }
341 
342  if (auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
343  auto operands = moduleTranslation.lookupValues(opInst.getOperands());
344  ArrayRef<llvm::Value *> operandsRef(operands);
345  if (auto attr = opInst.getAttrOfType<FlatSymbolRefAttr>("callee")) {
346  builder.CreateInvoke(moduleTranslation.lookupFunction(attr.getValue()),
347  moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
348  moduleTranslation.lookupBlock(invOp.getSuccessor(1)),
349  operandsRef);
350  } else {
351  auto *calleePtrType =
352  cast<llvm::PointerType>(operandsRef.front()->getType());
353  auto *calleeType =
354  cast<llvm::FunctionType>(calleePtrType->getElementType());
355  builder.CreateInvoke(calleeType, operandsRef.front(),
356  moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
357  moduleTranslation.lookupBlock(invOp.getSuccessor(1)),
358  operandsRef.drop_front());
359  }
360  return success();
361  }
362 
363  if (auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
364  llvm::Type *ty = moduleTranslation.convertType(lpOp.getType());
365  llvm::LandingPadInst *lpi =
366  builder.CreateLandingPad(ty, lpOp.getNumOperands());
367 
368  // Add clauses
369  for (llvm::Value *operand :
370  moduleTranslation.lookupValues(lpOp.getOperands())) {
371  // All operands should be constant - checked by verifier
372  if (auto *constOperand = dyn_cast<llvm::Constant>(operand))
373  lpi->addClause(constOperand);
374  }
375  moduleTranslation.mapValue(lpOp.getResult(), lpi);
376  return success();
377  }
378 
379  // Emit branches. We need to look up the remapped blocks and ignore the block
380  // arguments that were transformed into PHI nodes.
381  if (auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
382  llvm::BranchInst *branch =
383  builder.CreateBr(moduleTranslation.lookupBlock(brOp.getSuccessor()));
384  moduleTranslation.mapBranch(&opInst, branch);
385  setLoopMetadata(opInst, *branch, builder, moduleTranslation);
386  return success();
387  }
388  if (auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
389  llvm::MDNode *branchWeights = nullptr;
390  if (auto weights = condbrOp.getBranchWeights()) {
391  // Map weight attributes to LLVM metadata.
392  auto weightValues = weights->getValues<APInt>();
393  auto trueWeight = weightValues[0].getSExtValue();
394  auto falseWeight = weightValues[1].getSExtValue();
395  branchWeights =
396  llvm::MDBuilder(moduleTranslation.getLLVMContext())
397  .createBranchWeights(static_cast<uint32_t>(trueWeight),
398  static_cast<uint32_t>(falseWeight));
399  }
400  llvm::BranchInst *branch = builder.CreateCondBr(
401  moduleTranslation.lookupValue(condbrOp.getOperand(0)),
402  moduleTranslation.lookupBlock(condbrOp.getSuccessor(0)),
403  moduleTranslation.lookupBlock(condbrOp.getSuccessor(1)), branchWeights);
404  moduleTranslation.mapBranch(&opInst, branch);
405  setLoopMetadata(opInst, *branch, builder, moduleTranslation);
406  return success();
407  }
408  if (auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
409  llvm::MDNode *branchWeights = nullptr;
410  if (auto weights = switchOp.getBranchWeights()) {
411  llvm::SmallVector<uint32_t> weightValues;
412  weightValues.reserve(weights->size());
413  for (llvm::APInt weight : weights->cast<DenseIntElementsAttr>())
414  weightValues.push_back(weight.getLimitedValue());
415  branchWeights = llvm::MDBuilder(moduleTranslation.getLLVMContext())
416  .createBranchWeights(weightValues);
417  }
418 
419  llvm::SwitchInst *switchInst = builder.CreateSwitch(
420  moduleTranslation.lookupValue(switchOp.getValue()),
421  moduleTranslation.lookupBlock(switchOp.getDefaultDestination()),
422  switchOp.getCaseDestinations().size(), branchWeights);
423 
424  auto *ty = llvm::cast<llvm::IntegerType>(
425  moduleTranslation.convertType(switchOp.getValue().getType()));
426  for (auto i :
427  llvm::zip(switchOp.getCaseValues()->cast<DenseIntElementsAttr>(),
428  switchOp.getCaseDestinations()))
429  switchInst->addCase(
430  llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
431  moduleTranslation.lookupBlock(std::get<1>(i)));
432 
433  moduleTranslation.mapBranch(&opInst, switchInst);
434  return success();
435  }
436 
437  // Emit addressof. We need to look up the global value referenced by the
438  // operation and store it in the MLIR-to-LLVM value mapping. This does not
439  // emit any LLVM instruction.
440  if (auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
441  LLVM::GlobalOp global = addressOfOp.getGlobal();
442  LLVM::LLVMFuncOp function = addressOfOp.getFunction();
443 
444  // The verifier should not have allowed this.
445  assert((global || function) &&
446  "referencing an undefined global or function");
447 
448  moduleTranslation.mapValue(
449  addressOfOp.getResult(),
450  global ? moduleTranslation.lookupGlobal(global)
451  : moduleTranslation.lookupFunction(function.getName()));
452  return success();
453  }
454 
455  return failure();
456 }
457 
458 namespace {
459 /// Implementation of the dialect interface that converts operations belonging
460 /// to the LLVM dialect to LLVM IR.
461 class LLVMDialectLLVMIRTranslationInterface
463 public:
465 
466  /// Translates the given operation to LLVM IR using the provided IR builder
467  /// and saving the state in `moduleTranslation`.
469  convertOperation(Operation *op, llvm::IRBuilderBase &builder,
470  LLVM::ModuleTranslation &moduleTranslation) const final {
471  return convertOperationImpl(*op, builder, moduleTranslation);
472  }
473 };
474 } // end namespace
475 
477  registry.insert<LLVM::LLVMDialect>();
478  registry.addDialectInterface<LLVM::LLVMDialect,
479  LLVMDialectLLVMIRTranslationInterface>();
480 }
481 
483  DialectRegistry registry;
485  context.appendDialectRegistry(registry);
486 }
Include the generated interface declarations.
llvm::Constant * getLLVMConstant(llvm::Type *llvmType, Attribute attr, Location loc, const ModuleTranslation &moduleTranslation, bool isTopLevel=true)
Create an LLVM IR constant of llvmType from the MLIR attribute attr.
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
static Value min(ImplicitLocOpBuilder &builder, Value a, Value b)
operand_range getOperands()
Returns an iterator on the underlying Value&#39;s.
Definition: Operation.h:247
llvm::Type * convertType(Type type)
Converts the type from MLIR LLVM dialect to LLVM.
A symbol reference with a reference path containing a single element.
static llvm::MDNode * getLoopOptionMetadata(llvm::LLVMContext &ctx, LoopOptionCase option, int64_t value)
Returns an LLVM metadata node corresponding to a loop option.
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:327
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context...
llvm::LLVMContext & getLLVMContext() const
Returns the LLVM context in which the IR is being constructed.
static LogicalResult convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static void setLoopMetadata(Operation &opInst, llvm::Instruction &llvmInst, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
void mapLoopOptionsMetadata(Attribute options, llvm::MDNode *metadata)
SmallVector< llvm::Value * > lookupValues(ValueRange values)
Looks up remapped a list of remapped values.
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
static llvm::AtomicRMWInst::BinOp getLLVMAtomicBinOp(AtomicBinOp op)
static LLVMFunctionType get(Type result, ArrayRef< Type > arguments, bool isVarArg=false)
Gets or creates an instance of LLVM dialect function in the same context as the result type...
Definition: LLVMTypes.cpp:74
static constexpr const bool value
void addDialectInterface(TypeID interfaceTypeID, DialectInterfaceAllocatorFunction allocator)
Add an interface constructed with the given allocation function to the dialect provided as template p...
Definition: Dialect.h:347
Implementation class for module translation.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
void mapValue(Value mlir, llvm::Value *llvm)
Stores the mapping between an MLIR value and its LLVM IR counterpart.
Base class for dialect interfaces providing translation to LLVM IR.
MLIRContext & getContext()
Returns the MLIR context of the module being translated.
Attributes are known-constant values of operations.
Definition: Attributes.h:27
static llvm::CmpInst::Predicate getLLVMCmpPredicate(ICmpPredicate p)
Convert MLIR integer comparison predicate to LLVM IR comparison predicate.
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:276
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
void registerLLVMDialectTranslation(DialectRegistry &registry)
Register the LLVM dialect and the translation from it to the LLVM IR in the given registry;...
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
static llvm::FastMathFlags getFastmathFlags(FastmathFlagsInterface &op)
void mapBranch(Operation *mlir, llvm::Instruction *llvm)
Stores the mapping between an MLIR operation with successors and a corresponding LLVM IR instruction...
llvm::MDNode * getAccessGroup(Operation &opInst, SymbolRefAttr accessGroupRef) const
Returns the LLVM metadata corresponding to a reference to an mlir LLVM dialect access group operation...
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
Definition: Dialect.h:282
llvm::GlobalValue * lookupGlobal(Operation *op)
Finds an LLVM IR global value that corresponds to the given MLIR operation defining a global value...
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentCosts, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)
Contracts the specified cycle in the given graph in-place.
unsigned getNumResults()
Return the number of results held by this operation.
Definition: Operation.h:273
llvm::MDNode * lookupLoopOptionsMetadata(Attribute options) const
Returns the LLVM metadata corresponding to a llvm loop&#39;s codegen options attribute.
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:323
static llvm::AtomicOrdering getLLVMAtomicOrdering(AtomicOrdering ordering)
An attribute that represents a reference to a dense integer vector or tensor object.
static Value max(ImplicitLocOpBuilder &builder, Value a, Value b)