diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -419,28 +419,33 @@ /// ConstantExprs or ConstantGEPs). Value processConstant(llvm::Constant *constant); + /// Returns the entry block for the current insertion point. + Block *getConstantInsertionPoint() { + Region *region = nullptr; + if (builder.getInsertionBlock()) + region = builder.getInsertionBlock()->getParent(); + assert(region && "expected builder to insert into a region"); + return ®ion->front(); + } + /// Returns an iterator pointing to the first function or to the end of the + /// module if there is none. + Block::iterator getGlobalInsertionPoint() { + auto ops = module.getBody()->getOps(); + if (!ops.empty()) + return ops.begin(); + return module.getBody()->end(); + } + /// Returns an iterator pointing to the end of the module. + Block::iterator getFunctionInsertionPoint() { + return module.getBody()->end(); + } + /// Builder pointing at where the next Instruction should be generated. OpBuilder builder; /// The current context. MLIRContext *context; /// The current module being created. ModuleOp module; - /// The entry block of the current function being processed. - Block *currentEntryBlock = nullptr; - - /// Globals are inserted before the first function, if any. - Block::iterator getGlobalInsertPt() { - Block::iterator it = module.getBody()->begin(); - Block::iterator endIt = module.getBody()->end(); - while (it != endIt && !isa(it)) - ++it; - return it; - } - - /// Functions are always inserted before the module terminator. - Block::iterator getFuncInsertPt() { - return std::prev(module.getBody()->end()); - } /// Function-local mapping between original and imported block. DenseMap blockMapping; @@ -642,7 +647,10 @@ if (it != globals.end()) return it->second; - OpBuilder b(module.getBody(), getGlobalInsertPt()); + // Insert the global at the beginning of the module before the first function. + OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPoint(module.getBody(), getGlobalInsertionPoint()); + Attribute valueAttr; if (gv->hasInitializer()) valueAttr = getConstantAsAttr(gv->getInitializer()); @@ -655,20 +663,19 @@ alignment = align.value(); } - GlobalOp op = b.create( + GlobalOp op = builder.create( UnknownLoc::get(context), type, gv->isConstant(), convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr, alignment, /*addr_space=*/gv->getAddressSpace(), /*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal()); if (gv->hasInitializer() && !valueAttr) { - Region &r = op.getInitializerRegion(); - currentEntryBlock = b.createBlock(&r); - b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); - Value v = processConstant(gv->getInitializer()); - if (!v) + Block *block = builder.createBlock(&op.getInitializerRegion()); + builder.setInsertionPointToStart(block); + Value value = processConstant(gv->getInitializer()); + if (!value) return nullptr; - b.create(op.getLoc(), ArrayRef({v})); + builder.create(op.getLoc(), ArrayRef({value})); } if (gv->hasAtLeastLocalUnnamedAddr()) op.setUnnamedAddr(convertUnnamedAddrFromLLVM(gv->getUnnamedAddr())); @@ -679,28 +686,28 @@ } Value Importer::processConstant(llvm::Constant *constant) { - OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin()); + // Insert the constant at the beginning of the region entry block. + OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointToStart(getConstantInsertionPoint()); + if (Attribute attr = getConstantAsAttr(constant)) { // These constants can be represented as attributes. - OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); Type type = convertType(constant->getType()); if (auto symbolRef = attr.dyn_cast()) - return bEntry.create(UnknownLoc::get(context), type, - symbolRef.getValue()); - return bEntry.create(UnknownLoc::get(context), type, attr); + return builder.create(UnknownLoc::get(context), type, + symbolRef.getValue()); + return builder.create(UnknownLoc::get(context), type, attr); } if (auto *cn = dyn_cast(constant)) { Type type = convertType(cn->getType()); - return bEntry.create(UnknownLoc::get(context), type); + return builder.create(UnknownLoc::get(context), type); } if (auto *gv = dyn_cast(constant)) - return bEntry.create(UnknownLoc::get(context), - processGlobal(gv)); + return builder.create(UnknownLoc::get(context), + processGlobal(gv)); - if (auto *ce = dyn_cast(constant)) { - llvm::Instruction *i = ce->getAsInstruction(); - OpBuilder::InsertionGuard guard(builder); - builder.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); + if (auto *constExpr = dyn_cast(constant)) { + llvm::Instruction *i = constExpr->getAsInstruction(); if (failed(processInstruction(i))) return nullptr; assert(valueMapping.count(i)); @@ -720,7 +727,7 @@ } if (auto *ue = dyn_cast(constant)) { Type type = convertType(ue->getType()); - return bEntry.create(UnknownLoc::get(context), type); + return builder.create(UnknownLoc::get(context), type); } if (isa(constant) || @@ -747,22 +754,23 @@ bool useInsertValue = rootType.isa(); assert((useInsertValue || LLVM::isCompatibleVectorType(rootType)) && "unrecognized aggregate type"); - Value root = bEntry.create(UnknownLoc::get(context), rootType); + Value root = builder.create(UnknownLoc::get(context), rootType); for (unsigned i = 0; i < numElements; ++i) { llvm::Constant *element = getElement(i); Value elementValue = processConstant(element); if (!elementValue) return nullptr; if (useInsertValue) { - root = bEntry.create(UnknownLoc::get(context), root, - elementValue, i); + root = builder.create(UnknownLoc::get(context), root, + elementValue, i); } else { - Attribute indexAttr = bEntry.getI32IntegerAttr(static_cast(i)); - Value indexValue = bEntry.create( - UnknownLoc::get(context), bEntry.getI32Type(), indexAttr); + Attribute indexAttr = + builder.getI32IntegerAttr(static_cast(i)); + Value indexValue = builder.create( + UnknownLoc::get(context), builder.getI32Type(), indexAttr); if (!indexValue) return nullptr; - root = bEntry.create( + root = builder.create( UnknownLoc::get(context), rootType, root, elementValue, indexValue); } } @@ -1034,7 +1042,10 @@ bool dsoLocal = func->hasLocalLinkage(); CConv cconv = convertCConvFromLLVM(func->getCallingConv()); - builder.setInsertionPoint(module.getBody(), getFuncInsertPt()); + // Insert the function at the end of the module. + OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPoint(module.getBody(), getFunctionInsertionPoint()); + LLVMFuncOp funcOp = builder.create( UnknownLoc::get(context), func->getName(), functionType, convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv); @@ -1090,7 +1101,6 @@ builder.createBlock(&funcOp.getBody(), funcOp.getBody().end()); mapBlock(&bb, block); } - currentEntryBlock = &funcOp.getFunctionBody().getBlocks().front(); // Add function arguments to the entry block. for (const auto &it : llvm::enumerate(func->args())) { diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll --- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll @@ -1,9 +1,5 @@ ; RUN: mlir-translate -import-llvm %s | FileCheck %s -define void @intrinsics() { - ret void -} - ; CHECK-LABEL: llvm.func @fmuladd_test define void @fmuladd_test(float %0, float %1, <8 x float> %2, i8* %3) { ; CHECK: "llvm.intr.fmuladd"(%{{.*}}, %{{.*}}, %{{.*}}) : (f32, f32, f32) -> f32