Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp')
-rw-r--r--mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp111
1 files changed, 67 insertions, 44 deletions
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index e07524c9b1ed..104096fd46f7 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -175,6 +175,18 @@ public:
b.setInsertionPointToStart(module.getBody());
}
+ /// Stores the mapping between an LLVM value and its MLIR counterpart.
+ void mapValue(llvm::Value *llvm, Value mlir) { mapValue(llvm) = mlir; }
+
+ /// Provides write-once access to store the MLIR value corresponding to the
+ /// given LLVM value.
+ Value &mapValue(llvm::Value *value) {
+ Value &mlir = valueMapping[value];
+ assert(mlir == nullptr &&
+ "attempting to map a value that is already mapped");
+ return mlir;
+ }
+
/// Returns the remapped version of `value` or a placeholder that will be
/// remapped later if the defining instruction has not yet been visited.
Value processValue(llvm::Value *value);
@@ -196,8 +208,7 @@ public:
/// Converts an LLVM intrinsic to an MLIR LLVM dialect operation if an MLIR
/// counterpart exists. Otherwise, returns failure.
- LogicalResult convertIntrinsic(OpBuilder &odsBuilder,
- llvm::CallInst *callInst);
+ LogicalResult convertIntrinsic(OpBuilder &odsBuilder, llvm::CallInst *inst);
/// Imports `f` into the current module.
LogicalResult processFunction(llvm::Function *f);
@@ -214,7 +225,8 @@ private:
FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *f);
/// Imports `bb` into `block`, which must be initially empty.
LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block);
- /// Imports `inst` and populates instMap[inst] with the imported Value.
+ /// Imports `inst` and populates valueMapping[inst] with the result of the
+ /// imported operation.
LogicalResult processInstruction(llvm::Instruction *inst);
/// `br` branches to `target`. Append the block arguments to attach to the
/// generated branch op to `blockArguments`. These should be in the same order
@@ -258,8 +270,8 @@ private:
/// Remapped blocks, for the current function.
DenseMap<llvm::BasicBlock *, Block *> blocks;
- /// Remapped values. These are function-local.
- DenseMap<llvm::Value *, Value> instMap;
+ /// Mappings between original and imported values. These are function-local.
+ DenseMap<llvm::Value *, Value> valueMapping;
/// Instructions that had not been defined when first encountered as a use.
/// Maps to the dummy Operation that was created in processValue().
DenseMap<llvm::Value *, Operation *> unknownInstMap;
@@ -283,8 +295,9 @@ Type Importer::convertType(llvm::Type *type) {
}
LogicalResult Importer::convertIntrinsic(OpBuilder &odsBuilder,
- llvm::CallInst *callInst) {
- llvm::Function *callee = callInst->getCalledFunction();
+ llvm::CallInst *inst) {
+ // Check if the callee is an intrinsic.
+ llvm::Function *callee = inst->getCalledFunction();
if (!callee || !callee->isIntrinsic())
return failure();
@@ -293,6 +306,8 @@ LogicalResult Importer::convertIntrinsic(OpBuilder &odsBuilder,
if (!isConvertibleIntrinsic(intrinsicID))
return failure();
+ // Copy the call arguments to an operands array used by the conversion.
+ SmallVector<llvm::Value *> llvmOperands(inst->args());
#include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
return failure();
@@ -504,7 +519,7 @@ Value Importer::processConstant(llvm::Constant *c) {
b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
if (failed(processInstruction(i)))
return nullptr;
- assert(instMap.count(i));
+ assert(valueMapping.count(i));
// If we don't remove entry of `i` here, it's totally possible that the
// next time llvm::ConstantExpr::getAsInstruction is called again, which
@@ -512,8 +527,8 @@ Value Importer::processConstant(llvm::Constant *c) {
// created Instruction might be the same as `i`. Making processInstruction
// falsely believe that the new Instruction has been processed before
// and raised an assertion error.
- Value value = instMap[i];
- instMap.erase(i);
+ Value value = valueMapping[i];
+ valueMapping.erase(i);
// Remove this zombie LLVM instruction now, leaving us only with the MLIR
// op.
i->deleteValue();
@@ -574,8 +589,8 @@ Value Importer::processConstant(llvm::Constant *c) {
}
Value Importer::processValue(llvm::Value *value) {
- auto it = instMap.find(value);
- if (it != instMap.end())
+ auto it = valueMapping.find(value);
+ if (it != valueMapping.end())
return it->second;
// We don't expect to see instructions in dominator order. If we haven't seen
@@ -829,9 +844,13 @@ Importer::processBranchArgs(llvm::Instruction *br, llvm::BasicBlock *target,
LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
// FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math
// flags and call / operand attributes are not supported.
+
+ // Convert all intrinsics that provide an MLIR builder.
+ if (auto callInst = dyn_cast<llvm::CallInst>(inst))
+ if (succeeded(convertIntrinsic(b, callInst)))
+ return success();
+
Location loc = translateLoc(inst->getDebugLoc());
- assert(!instMap.count(inst) &&
- "processInstruction must be called only once per instruction!");
switch (inst->getOpcode()) {
default:
return emitError(loc) << "unknown instruction: " << diag(*inst);
@@ -886,24 +905,25 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
state.addOperands(ops);
Operation *op = b.create(state);
if (!inst->getType()->isVoidTy())
- instMap[inst] = op->getResult(0);
+ mapValue(inst, op->getResult(0));
return success();
}
case llvm::Instruction::Alloca: {
Value size = processValue(inst->getOperand(0));
auto *allocaInst = cast<llvm::AllocaInst>(inst);
- instMap[inst] =
- b.create<AllocaOp>(loc, convertType(inst->getType()),
- convertType(allocaInst->getAllocatedType()), size,
- allocaInst->getAlign().value());
+ Value res = b.create<AllocaOp>(loc, convertType(inst->getType()),
+ convertType(allocaInst->getAllocatedType()),
+ size, allocaInst->getAlign().value());
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::ICmp: {
Value lhs = processValue(inst->getOperand(0));
Value rhs = processValue(inst->getOperand(1));
- instMap[inst] = b.create<ICmpOp>(
+ Value res = b.create<ICmpOp>(
loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), lhs,
rhs);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::FCmp: {
@@ -921,9 +941,10 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
resType = VectorType::get({numElements}, boolType);
}
- instMap[inst] = b.create<FCmpOp>(
+ Value res = b.create<FCmpOp>(
loc, resType,
getFCmpPredicate(cast<llvm::FCmpInst>(inst)->getPredicate()), lhs, rhs);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::Br: {
@@ -987,17 +1008,12 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
}
case llvm::Instruction::PHI: {
Type type = convertType(inst->getType());
- instMap[inst] = b.getInsertionBlock()->addArgument(
- type, translateLoc(inst->getDebugLoc()));
+ mapValue(inst, b.getInsertionBlock()->addArgument(
+ type, translateLoc(inst->getDebugLoc())));
return success();
}
case llvm::Instruction::Call: {
llvm::CallInst *ci = cast<llvm::CallInst>(inst);
-
- // For all intrinsics, try to generate to the corresponding op.
- if (succeeded(convertIntrinsic(b, ci)))
- return success();
-
SmallVector<llvm::Value *> args(ci->args());
SmallVector<Value> ops = processValues(args);
SmallVector<Type, 2> tys;
@@ -1015,7 +1031,7 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
op = b.create<CallOp>(loc, tys, ops);
}
if (!ci->getType()->isVoidTy())
- instMap[inst] = op->getResult(0);
+ mapValue(inst, op->getResult(0));
return success();
}
case llvm::Instruction::LandingPad: {
@@ -1026,7 +1042,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
ops.push_back(processConstant(lpi->getClause(i)));
Type ty = convertType(lpi->getType());
- instMap[inst] = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
+ Value res = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::Invoke: {
@@ -1057,7 +1074,7 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
}
if (!ii->getType()->isVoidTy())
- instMap[inst] = op->getResult(0);
+ mapValue(inst, op->getResult(0));
return success();
}
case llvm::Instruction::Fence: {
@@ -1087,7 +1104,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
getLLVMAtomicOrdering(atomicInst->getOrdering());
Type type = convertType(inst->getType());
- instMap[inst] = b.create<AtomicRMWOp>(loc, type, binOp, ptr, val, ordering);
+ Value res = b.create<AtomicRMWOp>(loc, type, binOp, ptr, val, ordering);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::AtomicCmpXchg: {
@@ -1102,8 +1120,9 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
getLLVMAtomicOrdering(cmpXchgInst->getFailureOrdering());
Type type = convertType(inst->getType());
- instMap[inst] = b.create<AtomicCmpXchgOp>(loc, type, ptr, cmpVal, newVal,
- ordering, failOrdering);
+ Value res = b.create<AtomicCmpXchgOp>(loc, type, ptr, cmpVal, newVal,
+ ordering, failOrdering);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::GetElementPtr: {
@@ -1123,8 +1142,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
}
Type type = convertType(inst->getType());
- instMap[inst] =
- b.create<GEPOp>(loc, type, sourceElementType, basePtr, indices);
+ Value res = b.create<GEPOp>(loc, type, sourceElementType, basePtr, indices);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::InsertValue: {
@@ -1134,7 +1153,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
SmallVector<int64_t> indices;
llvm::append_range(indices, ivInst->getIndices());
- instMap[inst] = b.create<InsertValueOp>(loc, aggOperand, inserted, indices);
+ Value res = b.create<InsertValueOp>(loc, aggOperand, inserted, indices);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::ExtractValue: {
@@ -1143,7 +1163,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
SmallVector<int64_t> indices;
llvm::append_range(indices, evInst->getIndices());
- instMap[inst] = b.create<ExtractValueOp>(loc, aggOperand, indices);
+ Value res = b.create<ExtractValueOp>(loc, aggOperand, indices);
+ mapValue(inst, res);
return success();
}
case llvm::Instruction::ShuffleVector: {
@@ -1152,7 +1173,8 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
Value vec2 = processValue(svInst->getOperand(1));
SmallVector<int32_t> mask(svInst->getShuffleMask());
- instMap[inst] = b.create<ShuffleVectorOp>(loc, vec1, vec2, mask);
+ Value res = b.create<ShuffleVectorOp>(loc, vec1, vec2, mask);
+ mapValue(inst, res);
return success();
}
}
@@ -1191,7 +1213,7 @@ void Importer::processFunctionAttributes(llvm::Function *func,
LogicalResult Importer::processFunction(llvm::Function *f) {
blocks.clear();
- instMap.clear();
+ valueMapping.clear();
unknownInstMap.clear();
auto functionType =
@@ -1262,8 +1284,9 @@ LogicalResult Importer::processFunction(llvm::Function *f) {
// Add function arguments to the entry block.
for (const auto &kv : llvm::enumerate(f->args())) {
- instMap[&kv.value()] = blockList[0]->addArgument(
- functionType.getParamType(kv.index()), fop.getLoc());
+ mapValue(&kv.value(),
+ blockList[0]->addArgument(functionType.getParamType(kv.index()),
+ fop.getLoc()));
}
for (auto bbs : llvm::zip(*f, blockList)) {
@@ -1274,8 +1297,8 @@ LogicalResult Importer::processFunction(llvm::Function *f) {
// Now that all instructions are guaranteed to have been visited, ensure
// any unknown uses we encountered are remapped.
for (auto &llvmAndUnknown : unknownInstMap) {
- assert(instMap.count(llvmAndUnknown.first));
- Value newValue = instMap[llvmAndUnknown.first];
+ assert(valueMapping.count(llvmAndUnknown.first));
+ Value newValue = valueMapping[llvmAndUnknown.first];
Value oldValue = llvmAndUnknown.second->getResult(0);
oldValue.replaceAllUsesWith(newValue);
llvmAndUnknown.second->erase();