diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp --- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -493,8 +493,8 @@ case FixupTy::Codes::ArgumentAsLoad: { // Argument was pass-by-value, but is now pass-by-reference and // possibly with a different element type. - auto newArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); + auto newArg = func.front().insertArgument(fixup.index, + newInTys[fixup.index], loc); rewriter->setInsertionPointToStart(&func.front()); auto oldArgTy = ReferenceType::get(oldArgTys[fixup.index - offset]); auto cast = rewriter->create(loc, oldArgTy, newArg); @@ -505,8 +505,8 @@ case FixupTy::Codes::ArgumentType: { // Argument is pass-by-value, but its type has likely been modified to // suit the target ABI convention. - auto newArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); + auto newArg = func.front().insertArgument(fixup.index, + newInTys[fixup.index], loc); rewriter->setInsertionPointToStart(&func.front()); auto mem = rewriter->create(loc, newInTys[fixup.index]); @@ -524,8 +524,8 @@ case FixupTy::Codes::CharPair: { // The FIR boxchar argument has been split into a pair of distinct // arguments that are in juxtaposition to each other. - auto newArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); + auto newArg = func.front().insertArgument(fixup.index, + newInTys[fixup.index], loc); if (fixup.second == 1) { rewriter->setInsertionPointToStart(&func.front()); auto boxTy = oldArgTys[fixup.index - offset - fixup.second]; @@ -539,8 +539,8 @@ case FixupTy::Codes::ReturnAsStore: { // The value being returned is now being returned in memory (callee // stack space) through a hidden reference argument. - auto newArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); + auto newArg = func.front().insertArgument(fixup.index, + newInTys[fixup.index], loc); offset++; func.walk([&](mlir::ReturnOp ret) { rewriter->setInsertionPoint(ret); @@ -571,8 +571,8 @@ case FixupTy::Codes::Split: { // The FIR argument has been split into a pair of distinct arguments // that are in juxtaposition to each other. (For COMPLEX value.) - auto newArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); + auto newArg = func.front().insertArgument(fixup.index, + newInTys[fixup.index], loc); if (fixup.second == 1) { rewriter->setInsertionPointToStart(&func.front()); auto cplxTy = oldArgTys[fixup.index - offset - fixup.second]; @@ -594,9 +594,10 @@ // The first part of the pair appears in the original argument // position. The second part of the pair is appended after all the // original arguments. (Boxchar arguments.) - auto newBufArg = - func.front().insertArgument(fixup.index, newInTys[fixup.index]); - auto newLenArg = func.front().addArgument(trailingTys[fixup.second]); + auto newBufArg = func.front().insertArgument( + fixup.index, newInTys[fixup.index], loc); + auto newLenArg = + func.front().addArgument(trailingTys[fixup.second], loc); auto boxTy = oldArgTys[fixup.index - offset]; rewriter->setInsertionPointToStart(&func.front()); auto box = diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1534,9 +1534,11 @@ result.addTypes(v.getType()); mlir::Region *bodyRegion = result.addRegion(); bodyRegion->push_back(new Block{}); - bodyRegion->front().addArgument(builder.getIndexType()); - bodyRegion->front().addArgument(iterate.getType()); - bodyRegion->front().addArguments(iterArgs.getTypes()); + bodyRegion->front().addArgument(builder.getIndexType(), result.location); + bodyRegion->front().addArgument(iterate.getType(), result.location); + bodyRegion->front().addArguments( + iterArgs.getTypes(), + SmallVector(iterArgs.size(), result.location)); result.addAttributes(attributes); } @@ -1854,8 +1856,10 @@ bodyRegion->push_back(new Block{}); if (iterArgs.empty() && !finalCountValue) DoLoopOp::ensureTerminator(*bodyRegion, builder, result.location); - bodyRegion->front().addArgument(builder.getIndexType()); - bodyRegion->front().addArguments(iterArgs.getTypes()); + bodyRegion->front().addArgument(builder.getIndexType(), result.location); + bodyRegion->front().addArguments( + iterArgs.getTypes(), + SmallVector(iterArgs.size(), result.location)); if (unordered) result.addAttribute(unorderedAttrName(result.name), builder.getUnitAttr()); result.addAttributes(attributes); diff --git a/flang/lib/Optimizer/Transforms/AbstractResult.cpp b/flang/lib/Optimizer/Transforms/AbstractResult.cpp --- a/flang/lib/Optimizer/Transforms/AbstractResult.cpp +++ b/flang/lib/Optimizer/Transforms/AbstractResult.cpp @@ -231,7 +231,7 @@ mlir::OpBuilder rewriter(context); auto resultType = funcTy.getResult(0); auto argTy = getResultArgumentType(resultType, options); - options.newArg = func.front().insertArgument(zero, argTy); + options.newArg = func.front().insertArgument(zero, argTy, loc); if (mustEmboxResult(resultType, options)) { auto bufferType = fir::ReferenceType::get(resultType); rewriter.setInsertionPointToStart(&func.front()); diff --git a/flang/lib/Optimizer/Transforms/RewriteLoop.cpp b/flang/lib/Optimizer/Transforms/RewriteLoop.cpp --- a/flang/lib/Optimizer/Transforms/RewriteLoop.cpp +++ b/flang/lib/Optimizer/Transforms/RewriteLoop.cpp @@ -49,7 +49,7 @@ // conditional block since it already has the induction variable and // loop-carried values as arguments. auto *conditionalBlock = &loop.region().front(); - conditionalBlock->addArgument(rewriter.getIndexType()); + conditionalBlock->addArgument(rewriter.getIndexType(), loc); auto *firstBlock = rewriter.splitBlock(conditionalBlock, conditionalBlock->begin()); auto *lastBlock = &loop.region().back(); diff --git a/mlir/include/mlir-c/IR.h b/mlir/include/mlir-c/IR.h --- a/mlir/include/mlir-c/IR.h +++ b/mlir/include/mlir-c/IR.h @@ -531,7 +531,8 @@ /// Creates a new empty block with the given argument types and transfers /// ownership to the caller. MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs, - MlirType const *args); + MlirType const *args, + MlirLocation const *locs); /// Takes a block owned by the caller and destroys it. MLIR_CAPI_EXPORTED void mlirBlockDestroy(MlirBlock block); @@ -590,7 +591,8 @@ /// Appends an argument of the specified type to the block. Returns the newly /// added argument. MLIR_CAPI_EXPORTED MlirValue mlirBlockAddArgument(MlirBlock block, - MlirType type); + MlirType type, + MlirLocation loc); /// Returns `pos`-th argument of the block. MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, diff --git a/mlir/include/mlir/Dialect/GPU/GPUOps.td b/mlir/include/mlir/Dialect/GPU/GPUOps.td --- a/mlir/include/mlir/Dialect/GPU/GPUOps.td +++ b/mlir/include/mlir/Dialect/GPU/GPUOps.td @@ -246,7 +246,7 @@ /// Adds a new block argument that corresponds to buffers located in /// workgroup memory. - BlockArgument addWorkgroupAttribution(Type type); + BlockArgument addWorkgroupAttribution(Type type, Location loc); /// Returns the number of buffers located in the private memory. unsigned getNumPrivateAttributions() { @@ -267,7 +267,7 @@ /// Adds a new block argument that corresponds to buffers located in /// private memory. - BlockArgument addPrivateAttribution(Type type); + BlockArgument addPrivateAttribution(Type type, Location loc); /// Returns the name of the attribute containing the number of buffers /// located in the workgroup memory. diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td --- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td +++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td @@ -545,7 +545,8 @@ getOperation()->insertOperands(getNumControlOperands() + numInputs, operand); - getBody()->insertArgument(numLoops + numInputs, operand.getType()); + getBody()->insertArgument(numLoops + numInputs, operand.getType(), + getLoc()); getOperation()->setAttr( TiledLoopOp::getOperandSegmentSizeAttr(), builder.getI32VectorAttr( @@ -562,7 +563,7 @@ getOperation()->insertOperands( getNumControlOperands() + numInputs + numOutputs, operand); getBody()->insertArgument(numLoops + numInputs + numOutputs, - operand.getType()); + operand.getType(), getLoc()); getOperation()->setAttr( TiledLoopOp::getOperandSegmentSizeAttr(), builder.getI32VectorAttr( diff --git a/mlir/include/mlir/IR/Block.h b/mlir/include/mlir/IR/Block.h --- a/mlir/include/mlir/IR/Block.h +++ b/mlir/include/mlir/IR/Block.h @@ -88,21 +88,20 @@ bool args_empty() { return arguments.empty(); } /// Add one value to the argument list. - BlockArgument addArgument(Type type, Optional loc = {}); + BlockArgument addArgument(Type type, Location loc); /// Insert one value to the position in the argument list indicated by the /// given iterator. The existing arguments are shifted. The block is expected /// not to have predecessors. - BlockArgument insertArgument(args_iterator it, Type type, - Optional loc = {}); + BlockArgument insertArgument(args_iterator it, Type type, Location loc); /// Add one argument to the argument list for each type specified in the list. + /// `locs` is required to have the same number of elements as `types`. iterator_range addArguments(TypeRange types, - ArrayRef locs = {}); + ArrayRef locs); /// Add one value to the argument list at the specified position. - BlockArgument insertArgument(unsigned index, Type type, - Optional loc = {}); + BlockArgument insertArgument(unsigned index, Type type, Location loc); /// Erase the argument at 'index' and remove it from the argument list. void eraseArgument(unsigned index); diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -384,15 +384,18 @@ /// Add new block with 'argTypes' arguments and set the insertion point to the /// end of it. The block is inserted at the provided insertion point of - /// 'parent'. + /// 'parent'. `locs` contains the locations of the inserted arguments, and + /// should match the size of `argTypes`. Block *createBlock(Region *parent, Region::iterator insertPt = {}, TypeRange argTypes = llvm::None, - ArrayRef locs = {}); + ArrayRef locs = llvm::None); /// Add new block with 'argTypes' arguments and set the insertion point to the - /// end of it. The block is placed before 'insertBefore'. + /// end of it. The block is placed before 'insertBefore'. `locs` contains the + /// locations of the inserted arguments, and should match the size of + /// `argTypes`. Block *createBlock(Block *insertBefore, TypeRange argTypes = llvm::None, - ArrayRef locs = {}); + ArrayRef locs = llvm::None); //===--------------------------------------------------------------------===// // Operation Creation diff --git a/mlir/include/mlir/IR/FunctionImplementation.h b/mlir/include/mlir/IR/FunctionImplementation.h --- a/mlir/include/mlir/IR/FunctionImplementation.h +++ b/mlir/include/mlir/IR/FunctionImplementation.h @@ -60,7 +60,7 @@ OpAsmParser &parser, bool allowAttributes, bool allowVariadic, SmallVectorImpl &argNames, SmallVectorImpl &argTypes, SmallVectorImpl &argAttrs, - SmallVectorImpl> &argLocations, bool &isVariadic); + SmallVectorImpl &argLocations, bool &isVariadic); /// Parses a function signature using `parser`. The `allowVariadic` argument /// indicates whether functions with variadic arguments are supported. The @@ -71,7 +71,7 @@ SmallVectorImpl &argNames, SmallVectorImpl &argTypes, SmallVectorImpl &argAttrs, - SmallVectorImpl> &argLocations, + SmallVectorImpl &argLocations, bool &isVariadic, SmallVectorImpl &resultTypes, SmallVectorImpl &resultAttrs); diff --git a/mlir/include/mlir/IR/FunctionInterfaces.h b/mlir/include/mlir/IR/FunctionInterfaces.h --- a/mlir/include/mlir/IR/FunctionInterfaces.h +++ b/mlir/include/mlir/IR/FunctionInterfaces.h @@ -72,7 +72,7 @@ void insertFunctionArguments(Operation *op, ArrayRef argIndices, TypeRange argTypes, ArrayRef argAttrs, - ArrayRef> argLocs, + ArrayRef argLocs, unsigned originalNumArgs, Type newType); /// Insert the specified results and update the function type attribute. diff --git a/mlir/include/mlir/IR/FunctionInterfaces.td b/mlir/include/mlir/IR/FunctionInterfaces.td --- a/mlir/include/mlir/IR/FunctionInterfaces.td +++ b/mlir/include/mlir/IR/FunctionInterfaces.td @@ -156,7 +156,13 @@ assert(empty() && "function already has an entry block"); Block *entry = new Block(); push_back(entry); - entry->addArguments($_op.getArgumentTypes()); + + // FIXME: Allow for passing in locations for these arguments instead of using + // the operations location. + ArrayRef inputTypes = $_op.getArgumentTypes(); + SmallVector locations(inputTypes.size(), + $_op.getOperation()->getLoc()); + entry->addArguments(inputTypes, locations); return entry; } @@ -234,7 +240,7 @@ /// Insert a single argument of type `argType` with attributes `argAttrs` and /// location `argLoc` at `argIndex`. void insertArgument(unsigned argIndex, Type argType, DictionaryAttr argAttrs, - Optional argLoc = {}) { + Location argLoc) { insertArguments({argIndex}, {argType}, {argAttrs}, {argLoc}); } @@ -244,7 +250,7 @@ /// appear in the same order that they were listed here. void insertArguments(ArrayRef argIndices, TypeRange argTypes, ArrayRef argAttrs, - ArrayRef> argLocs) { + ArrayRef argLocs) { unsigned originalNumArgs = $_op.getNumArguments(); Type newType = $_op.getTypeWithArgsAndResults( argIndices, argTypes, /*resultIndices=*/{}, /*resultTypes=*/{}); diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -1209,22 +1209,22 @@ /// Parses a region. Any parsed blocks are appended to 'region' and must be /// moved to the op regions after the op is created. The first block of the /// region takes 'arguments' of types 'argTypes'. If `argLocations` is - /// non-empty it contains an optional location to be attached to each - /// argument. If 'enableNameShadowing' is set to true, the argument names are - /// allowed to shadow the names of other existing SSA values defined above the - /// region scope. 'enableNameShadowing' can only be set to true for regions - /// attached to operations that are 'IsolatedFromAbove'. - virtual ParseResult - parseRegion(Region ®ion, ArrayRef arguments = {}, - ArrayRef argTypes = {}, - ArrayRef> argLocations = {}, - bool enableNameShadowing = false) = 0; + /// non-empty it contains a location to be attached to each argument. If + /// 'enableNameShadowing' is set to true, the argument names are allowed to + /// shadow the names of other existing SSA values defined above the region + /// scope. 'enableNameShadowing' can only be set to true for regions attached + /// to operations that are 'IsolatedFromAbove'. + virtual ParseResult parseRegion(Region ®ion, + ArrayRef arguments = {}, + ArrayRef argTypes = {}, + ArrayRef argLocations = {}, + bool enableNameShadowing = false) = 0; /// Parses a region if present. virtual OptionalParseResult parseOptionalRegion(Region ®ion, ArrayRef arguments = {}, ArrayRef argTypes = {}, - ArrayRef> argLocations = {}, + ArrayRef argLocations = {}, bool enableNameShadowing = false) = 0; /// Parses a region if present. If the region is present, a new region is diff --git a/mlir/include/mlir/IR/Region.h b/mlir/include/mlir/IR/Region.h --- a/mlir/include/mlir/IR/Region.h +++ b/mlir/include/mlir/IR/Region.h @@ -82,6 +82,7 @@ return empty() ? BlockArgListType() : front().getArguments(); } + /// Returns the argument types of the first block within the region. ValueTypeRange getArgumentTypes(); using args_iterator = BlockArgListType::iterator; @@ -94,21 +95,26 @@ bool args_empty() { return getArguments().empty(); } /// Add one value to the argument list. - BlockArgument addArgument(Type type) { return front().addArgument(type); } + BlockArgument addArgument(Type type, Location loc) { + return front().addArgument(type, loc); + } /// Insert one value to the position in the argument list indicated by the /// given iterator. The existing arguments are shifted. The block is expected /// not to have predecessors. - BlockArgument insertArgument(args_iterator it, Type type) { - return front().insertArgument(it, type); + BlockArgument insertArgument(args_iterator it, Type type, Location loc) { + return front().insertArgument(it, type, loc); } /// Add one argument to the argument list for each type specified in the list. - iterator_range addArguments(TypeRange types); + /// `locs` contains the locations for each of the new arguments, and must be + /// of equal size to `types`. + iterator_range addArguments(TypeRange types, + ArrayRef locs); /// Add one value to the argument list at the specified position. - BlockArgument insertArgument(unsigned index, Type type) { - return front().insertArgument(index, type); + BlockArgument insertArgument(unsigned index, Type type, Location loc) { + return front().insertArgument(index, type, loc); } /// Erase the argument at 'index' and remove it from the argument list. diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp --- a/mlir/lib/Bindings/Python/IRCore.cpp +++ b/mlir/lib/Bindings/Python/IRCore.cpp @@ -325,12 +325,18 @@ PyBlock appendBlock(const py::args &pyArgTypes) { operation->checkValid(); llvm::SmallVector argTypes; + llvm::SmallVector argLocs; argTypes.reserve(pyArgTypes.size()); + argLocs.reserve(pyArgTypes.size()); for (auto &pyArg : pyArgTypes) { argTypes.push_back(pyArg.cast()); + // TODO: Pass in a proper location here. + argLocs.push_back( + mlirLocationUnknownGet(mlirTypeGetContext(argTypes.back()))); } - MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data()); + MlirBlock block = + mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data()); mlirRegionAppendOwnedBlock(region, block); return PyBlock(operation, block); } @@ -2717,12 +2723,18 @@ [](PyRegion &parent, py::list pyArgTypes) { parent.checkValid(); llvm::SmallVector argTypes; + llvm::SmallVector argLocs; argTypes.reserve(pyArgTypes.size()); + argLocs.reserve(pyArgTypes.size()); for (auto &pyArg : pyArgTypes) { argTypes.push_back(pyArg.cast()); + // TODO: Pass in a proper location here. + argLocs.push_back( + mlirLocationUnknownGet(mlirTypeGetContext(argTypes.back()))); } - MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data()); + MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data(), + argLocs.data()); mlirRegionInsertOwnedBlock(parent, 0, block); return PyBlock(parent.getParentOperation(), block); }, @@ -2734,12 +2746,18 @@ [](PyBlock &self, py::args pyArgTypes) { self.checkValid(); llvm::SmallVector argTypes; + llvm::SmallVector argLocs; argTypes.reserve(pyArgTypes.size()); + argLocs.reserve(pyArgTypes.size()); for (auto &pyArg : pyArgTypes) { argTypes.push_back(pyArg.cast()); + // TODO: Pass in a proper location here. + argLocs.push_back( + mlirLocationUnknownGet(mlirTypeGetContext(argTypes.back()))); } - MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data()); + MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data(), + argLocs.data()); MlirRegion region = mlirBlockGetParentRegion(self.get()); mlirRegionInsertOwnedBlockBefore(region, self.get(), block); return PyBlock(self.getParentOperation(), block); @@ -2751,12 +2769,18 @@ [](PyBlock &self, py::args pyArgTypes) { self.checkValid(); llvm::SmallVector argTypes; + llvm::SmallVector argLocs; argTypes.reserve(pyArgTypes.size()); + argLocs.reserve(pyArgTypes.size()); for (auto &pyArg : pyArgTypes) { argTypes.push_back(pyArg.cast()); - } - MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data()); + // TODO: Pass in a proper location here. + argLocs.push_back( + mlirLocationUnknownGet(mlirTypeGetContext(argTypes.back()))); + } + MlirBlock block = mlirBlockCreate(argTypes.size(), argTypes.data(), + argLocs.data()); MlirRegion region = mlirBlockGetParentRegion(self.get()); mlirRegionInsertOwnedBlockAfter(region, self.get(), block); return PyBlock(self.getParentOperation(), block); diff --git a/mlir/lib/CAPI/Dialect/Linalg.cpp b/mlir/lib/CAPI/Dialect/Linalg.cpp --- a/mlir/lib/CAPI/Dialect/Linalg.cpp +++ b/mlir/lib/CAPI/Dialect/Linalg.cpp @@ -28,12 +28,15 @@ "Expected Linalg op with 0 blocks"); SmallVector argTypes; - for (OpOperand *opOperand : linalgOp.getInputAndOutputOperands()) + SmallVector argLocs; + for (OpOperand *opOperand : linalgOp.getInputAndOutputOperands()) { argTypes.push_back(getElementTypeOrSelf(opOperand->get().getType())); + argLocs.push_back(opOperand->get().getLoc()); + } ImplicitLocOpBuilder b(op->getLoc(), op->getContext()); Region ®ion = op->getRegion(0); - Block *body = b.createBlock(®ion, /*insertPt=*/{}, argTypes); + Block *body = b.createBlock(®ion, /*insertPt=*/{}, argTypes, argLocs); b.setInsertionPointToStart(body); fun(b, *body); } diff --git a/mlir/lib/CAPI/IR/IR.cpp b/mlir/lib/CAPI/IR/IR.cpp --- a/mlir/lib/CAPI/IR/IR.cpp +++ b/mlir/lib/CAPI/IR/IR.cpp @@ -535,10 +535,11 @@ // Block API. //===----------------------------------------------------------------------===// -MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args) { +MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args, + MlirLocation const *locs) { Block *b = new Block; for (intptr_t i = 0; i < nArgs; ++i) - b->addArgument(unwrap(args[i])); + b->addArgument(unwrap(args[i]), unwrap(locs[i])); return wrap(b); } @@ -618,8 +619,9 @@ return static_cast(unwrap(block)->getNumArguments()); } -MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type) { - return wrap(unwrap(block)->addArgument(unwrap(type))); +MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type, + MlirLocation loc) { + return wrap(unwrap(block)->addArgument(unwrap(type), unwrap(loc))); } MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos) { diff --git a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp --- a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp +++ b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp @@ -208,8 +208,10 @@ if (allocaScopeOp.getNumResults() == 0) { continueBlock = remainingOpsBlock; } else { - continueBlock = rewriter.createBlock(remainingOpsBlock, - allocaScopeOp.getResultTypes()); + continueBlock = rewriter.createBlock( + remainingOpsBlock, allocaScopeOp.getResultTypes(), + SmallVector(allocaScopeOp->getNumResults(), + allocaScopeOp.getLoc())); rewriter.create(loc, ValueRange(), remainingOpsBlock); } @@ -1019,7 +1021,7 @@ Block::iterator remainingOpsIt = std::next(rewriter.getInsertionPoint()); Block *condBlock = rewriter.createBlock(initBlock->getParent(), {}, - {indexType, indexType}); + {indexType, indexType}, {loc, loc}); // Move the remaining initBlock ops to condBlock. Block *remainingBlock = rewriter.splitBlock(initBlock, remainingOpsIt); diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp --- a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp +++ b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp @@ -628,7 +628,8 @@ Position *inputPos = valueToPosition.lookup(oldValue); assert(inputPos && "expected value to be a pattern input"); usedMatchValues.push_back(inputPos); - return newValue = rewriterFunc.front().addArgument(oldValue.getType()); + return newValue = rewriterFunc.front().addArgument(oldValue.getType(), + oldValue.getLoc()); }; // If this is a custom rewriter, simply dispatch to the registered rewrite diff --git a/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp b/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp --- a/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp +++ b/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp @@ -188,7 +188,7 @@ Type type = reduce.getOperand().getType(); builder.createBlock(&decl.initializerRegion(), decl.initializerRegion().end(), - {type}); + {type}, {reduce.getOperand().getLoc()}); builder.setInsertionPointToEnd(&decl.initializerRegion().back()); Value init = builder.create(reduce.getLoc(), type, initValue); @@ -214,8 +214,10 @@ OpBuilder::InsertionGuard guard(builder); Type type = reduce.getOperand().getType(); Type ptrType = LLVM::LLVMPointerType::get(type); + Location reduceOperandLoc = reduce.getOperand().getLoc(); builder.createBlock(&decl.atomicReductionRegion(), - decl.atomicReductionRegion().end(), {ptrType, ptrType}); + decl.atomicReductionRegion().end(), {ptrType, ptrType}, + {reduceOperandLoc, reduceOperandLoc}); Block *atomicBlock = &decl.atomicReductionRegion().back(); builder.setInsertionPointToEnd(atomicBlock); Value loaded = builder.create(reduce.getLoc(), diff --git a/mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp b/mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp --- a/mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp +++ b/mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp @@ -177,10 +177,11 @@ loopOp.body().getBlocks().insert(getBlockIt(loopOp.body(), 1), header); // Create the new induction variable to use. + Value adapLowerBound = adaptor.getLowerBound(); BlockArgument newIndVar = - header->addArgument(adaptor.getLowerBound().getType()); + header->addArgument(adapLowerBound.getType(), adapLowerBound.getLoc()); for (Value arg : adaptor.getInitArgs()) - header->addArgument(arg.getType()); + header->addArgument(arg.getType(), arg.getLoc()); Block *body = forOp.getBody(); // Apply signature conversion to the body of the forOp. It has a single block, diff --git a/mlir/lib/Conversion/SCFToStandard/SCFToStandard.cpp b/mlir/lib/Conversion/SCFToStandard/SCFToStandard.cpp --- a/mlir/lib/Conversion/SCFToStandard/SCFToStandard.cpp +++ b/mlir/lib/Conversion/SCFToStandard/SCFToStandard.cpp @@ -368,7 +368,8 @@ continueBlock = remainingOpsBlock; } else { continueBlock = - rewriter.createBlock(remainingOpsBlock, ifOp.getResultTypes()); + rewriter.createBlock(remainingOpsBlock, ifOp.getResultTypes(), + SmallVector(ifOp.getNumResults(), loc)); rewriter.create(loc, remainingOpsBlock); } @@ -433,9 +434,10 @@ rewriter.inlineRegionBefore(region, remainingOpsBlock); SmallVector vals; - for (auto arg : remainingOpsBlock->addArguments(op->getResultTypes())) { + SmallVector argLocs(op.getNumResults(), op->getLoc()); + for (auto arg : + remainingOpsBlock->addArguments(op->getResultTypes(), argLocs)) vals.push_back(arg); - } rewriter.replaceOp(op, vals); return success(); } diff --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp --- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp @@ -812,9 +812,9 @@ // Split the block into initial, loop, and ending parts. auto *initBlock = rewriter.getInsertionBlock(); - auto *loopBlock = - rewriter.createBlock(initBlock->getParent(), - std::next(Region::iterator(initBlock)), valueType); + auto *loopBlock = rewriter.createBlock( + initBlock->getParent(), std::next(Region::iterator(initBlock)), + valueType, loc); auto *endBlock = rewriter.createBlock( loopBlock->getParent(), std::next(Region::iterator(loopBlock))); diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp --- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp +++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp @@ -267,10 +267,13 @@ SmallVector operands = {args[0], leadingZeros, zero}; SmallVector types = {elementTy, elementTy, elementTy}; + SmallVector locations = {loc, loc, loc}; auto whileOp = rewriter.create(loc, types, operands); - Block *before = rewriter.createBlock(&whileOp.getBefore(), {}, types); - Block *after = rewriter.createBlock(&whileOp.getAfter(), {}, types); + Block *before = + rewriter.createBlock(&whileOp.getBefore(), {}, types, locations); + Block *after = + rewriter.createBlock(&whileOp.getAfter(), {}, types, locations); // The conditional block of the while loop. { @@ -1409,7 +1412,7 @@ OpBuilder::InsertionGuard regionGuard(rewriter); rewriter.createBlock(&genericOp.region(), genericOp.region().end(), - TypeRange({resultElementTy})); + TypeRange({resultElementTy}), loc); Value batch = rewriter.create(loc, 0); Value y = rewriter.create(loc, 1); Value x = rewriter.create(loc, 2); @@ -2159,9 +2162,9 @@ { OpBuilder::InsertionGuard regionGuard(rewriter); - Block *block = - rewriter.createBlock(&genericOp.region(), genericOp.region().end(), - TypeRange({inputElementTy, resultElementTy})); + Block *block = rewriter.createBlock( + &genericOp.region(), genericOp.region().end(), + TypeRange({inputElementTy, resultElementTy}), {loc, loc}); auto inputValue = block->getArgument(0); rewriter.setInsertionPointToStart(block); diff --git a/mlir/lib/Conversion/VectorToGPU/VectorToGPU.cpp b/mlir/lib/Conversion/VectorToGPU/VectorToGPU.cpp --- a/mlir/lib/Conversion/VectorToGPU/VectorToGPU.cpp +++ b/mlir/lib/Conversion/VectorToGPU/VectorToGPU.cpp @@ -435,8 +435,8 @@ newLoop.getLoopBody().getBlocks().splice( newLoop.getLoopBody().getBlocks().begin(), loop.getLoopBody().getBlocks()); - for (auto operand : newIterOperands) - newLoop.getBody()->addArgument(operand.getType()); + for (Value operand : newIterOperands) + newLoop.getBody()->addArgument(operand.getType(), operand.getLoc()); for (auto it : llvm::zip(loop.getResults(), newLoop.getResults().take_front( loop.getNumResults()))) diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -1279,9 +1279,10 @@ Region *bodyRegion = result.addRegion(); bodyRegion->push_back(new Block); Block &bodyBlock = bodyRegion->front(); - Value inductionVar = bodyBlock.addArgument(builder.getIndexType()); + Value inductionVar = + bodyBlock.addArgument(builder.getIndexType(), result.location); for (Value val : iterArgs) - bodyBlock.addArgument(val.getType()); + bodyBlock.addArgument(val.getType(), val.getLoc()); // Create the default terminator if the builder is not provided and if the // iteration arguments are not provided. Otherwise, leave this to the caller @@ -1965,7 +1966,7 @@ // Take the body of the original parent loop. newLoop.getLoopBody().takeBody(loop.getLoopBody()); for (Value val : newIterArgs) - newLoop.getLoopBody().addArgument(val.getType()); + newLoop.getLoopBody().addArgument(val.getType(), val.getLoc()); // Update yield operation with new values to be added. if (!newYieldedValues.empty()) { @@ -2887,7 +2888,7 @@ auto *body = new Block(); // Add all the block arguments. for (unsigned i = 0, e = steps.size(); i < e; ++i) - body->addArgument(IndexType::get(builder.getContext())); + body->addArgument(IndexType::get(builder.getContext()), result.location); bodyRegion->push_back(body); if (resultTypes.empty()) ensureTerminator(*bodyRegion, builder, result.location); diff --git a/mlir/lib/Dialect/Async/IR/Async.cpp b/mlir/lib/Dialect/Async/IR/Async.cpp --- a/mlir/lib/Dialect/Async/IR/Async.cpp +++ b/mlir/lib/Dialect/Async/IR/Async.cpp @@ -107,7 +107,8 @@ for (Value operand : operands) { auto valueType = operand.getType().dyn_cast(); bodyBlock.addArgument(valueType ? valueType.getValueType() - : operand.getType()); + : operand.getType(), + operand.getLoc()); } // Create the default terminator if the builder is not provided and if the diff --git a/mlir/lib/Dialect/Async/Transforms/AsyncParallelFor.cpp b/mlir/lib/Dialect/Async/Transforms/AsyncParallelFor.cpp --- a/mlir/lib/Dialect/Async/Transforms/AsyncParallelFor.cpp +++ b/mlir/lib/Dialect/Async/Transforms/AsyncParallelFor.cpp @@ -270,7 +270,9 @@ rewriter.getListener()->notifyOperationInserted(func); // Create function entry block. - Block *block = b.createBlock(&func.getBody(), func.begin(), type.getInputs()); + Block *block = + b.createBlock(&func.getBody(), func.begin(), type.getInputs(), + SmallVector(type.getNumInputs(), op.getLoc())); b.setInsertionPointToEnd(block); ParallelComputeFunctionArgs args = {op.getNumLoops(), func.getArguments()}; @@ -482,7 +484,8 @@ rewriter.getListener()->notifyOperationInserted(func); // Create function entry block. - Block *block = b.createBlock(&func.getBody(), func.begin(), type.getInputs()); + Block *block = b.createBlock(&func.getBody(), func.begin(), type.getInputs(), + SmallVector(type.getNumInputs(), loc)); b.setInsertionPointToEnd(block); Type indexTy = b.getIndexType(); @@ -499,11 +502,12 @@ // Create a work splitting while loop for the [blockStart, blockEnd) range. SmallVector types = {indexTy, indexTy}; SmallVector operands = {blockStart, blockEnd}; + SmallVector locations = {loc, loc}; // Create a recursive dispatch loop. scf::WhileOp whileOp = b.create(types, operands); - Block *before = b.createBlock(&whileOp.getBefore(), {}, types); - Block *after = b.createBlock(&whileOp.getAfter(), {}, types); + Block *before = b.createBlock(&whileOp.getBefore(), {}, types, locations); + Block *after = b.createBlock(&whileOp.getAfter(), {}, types, locations); // Setup dispatch loop condition block: decide if we need to go into the // `after` block and launch one more async dispatch. diff --git a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp --- a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp +++ b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp @@ -369,8 +369,8 @@ // the rest have the same types as the data operands. Region *kernelRegion = result.addRegion(); Block *body = new Block(); - body->addArguments( - std::vector(kNumConfigRegionAttributes, builder.getIndexType())); + for (unsigned i = 0; i < kNumConfigRegionAttributes; ++i) + body->addArgument(builder.getIndexType(), result.location); kernelRegion->push_back(body); } @@ -671,7 +671,7 @@ if (parser.parseOptionalKeyword("args")) return success(); SmallVector argAttrs; - SmallVector> argLocations; + SmallVector argLocations; bool isVariadic = false; return function_interface_impl::parseFunctionArgumentList( parser, /*allowAttributes=*/false, @@ -699,21 +699,21 @@ /// Adds a new block argument that corresponds to buffers located in /// workgroup memory. -BlockArgument GPUFuncOp::addWorkgroupAttribution(Type type) { +BlockArgument GPUFuncOp::addWorkgroupAttribution(Type type, Location loc) { auto attrName = getNumWorkgroupAttributionsAttrName(); auto attr = (*this)->getAttrOfType(attrName); (*this)->setAttr(attrName, IntegerAttr::get(attr.getType(), attr.getValue() + 1)); return getBody().insertArgument(getType().getNumInputs() + attr.getInt(), - type); + type, loc); } /// Adds a new block argument that corresponds to buffers located in /// private memory. -BlockArgument GPUFuncOp::addPrivateAttribution(Type type) { +BlockArgument GPUFuncOp::addPrivateAttribution(Type type, Location loc) { // Buffers on the private memory always come after buffers on the workgroup // memory. - return getBody().addArgument(type); + return getBody().addArgument(type, loc); } void GPUFuncOp::build(OpBuilder &builder, OperationState &result, @@ -729,9 +729,14 @@ result.addAttributes(attrs); Region *body = result.addRegion(); Block *entryBlock = new Block; - entryBlock->addArguments(type.getInputs()); - entryBlock->addArguments(workgroupAttributions); - entryBlock->addArguments(privateAttributions); + + // TODO: Allow passing in proper locations here. + for (Type type : type.getInputs()) + entryBlock->addArgument(type, result.location); + for (Type type : workgroupAttributions) + entryBlock->addArgument(type, result.location); + for (Type type : privateAttributions) + entryBlock->addArgument(type, result.location); body->getBlocks().push_back(entryBlock); } @@ -783,7 +788,7 @@ SmallVector resultAttrs; SmallVector argTypes; SmallVector resultTypes; - SmallVector> argLocations; + SmallVector argLocations; bool isVariadic; // Parse the function name. diff --git a/mlir/lib/Dialect/GPU/Transforms/AllReduceLowering.cpp b/mlir/lib/Dialect/GPU/Transforms/AllReduceLowering.cpp --- a/mlir/lib/Dialect/GPU/Transforms/AllReduceLowering.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/AllReduceLowering.cpp @@ -157,11 +157,12 @@ /// Adds type to funcOp's workgroup attributions. Value createWorkgroupBuffer() { + // TODO: Pick a proper location for the attribution. int workgroupMemoryAddressSpace = gpu::GPUDialect::getWorkgroupAddressSpace(); auto bufferType = MemRefType::get({kSubgroupSize}, valueType, AffineMap{}, workgroupMemoryAddressSpace); - return funcOp.addWorkgroupAttribution(bufferType); + return funcOp.addWorkgroupAttribution(bufferType, rewriter.getUnknownLoc()); } /// Returns an accumulator factory using either the op attribute or the body @@ -207,7 +208,7 @@ // Return accumulator result. rewriter.setInsertionPointToStart(split); - return split->addArgument(lhs.getType()); + return split->addArgument(lhs.getType(), lhs.getLoc()); }); } @@ -298,7 +299,7 @@ assert(thenOperands.size() == elseOperands.size()); rewriter.setInsertionPointToStart(continueBlock); for (auto operand : thenOperands) - continueBlock->addArgument(operand.getType()); + continueBlock->addArgument(operand.getType(), operand.getLoc()); } /// Shortcut for createIf with empty else block and no block operands. diff --git a/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp b/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp --- a/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp @@ -252,7 +252,9 @@ executeOp.operandsMutable().append(asyncTokens); SmallVector tokenTypes( asyncTokens.size(), builder.getType()); - copy(executeOp.getBody()->addArguments(tokenTypes), + SmallVector tokenLocs(asyncTokens.size(), + executeOp.getLoc()); + copy(executeOp.getBody()->addArguments(tokenTypes, tokenLocs), std::back_inserter(tokens)); }); diff --git a/mlir/lib/Dialect/GPU/Transforms/MemoryPromotion.cpp b/mlir/lib/Dialect/GPU/Transforms/MemoryPromotion.cpp --- a/mlir/lib/Dialect/GPU/Transforms/MemoryPromotion.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/MemoryPromotion.cpp @@ -150,8 +150,7 @@ int workgroupMemoryAddressSpace = gpu::GPUDialect::getWorkgroupAddressSpace(); auto bufferType = MemRefType::get(type.getShape(), type.getElementType(), {}, workgroupMemoryAddressSpace); - - Value attribution = op.addWorkgroupAttribution(bufferType); + Value attribution = op.addWorkgroupAttribution(bufferType, value.getLoc()); // Replace the uses first since only the original uses are currently present. // Then insert the copies. diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -1952,9 +1952,10 @@ auto *entry = new Block; push_back(entry); + // FIXME: Allow passing in proper locations for the entry arguments. LLVMFunctionType type = getType(); for (unsigned i = 0, e = type.getNumParams(); i < e; ++i) - entry->addArgument(type.getParamType(i)); + entry->addArgument(type.getParamType(i), getLoc()); return entry; } @@ -2038,7 +2039,7 @@ SmallVector resultAttrs; SmallVector argTypes; SmallVector resultTypes; - SmallVector> argLocations; + SmallVector argLocations; bool isVariadic; auto signatureLocation = parser.getCurrentLocation(); diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp --- a/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp +++ b/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp @@ -48,7 +48,8 @@ for (int position : llvm::drop_begin(successor.second, 1)) { Block *dummyBlock = builder.createBlock(bb.getParent()); terminator->setSuccessor(dummyBlock, position); - dummyBlock->addArguments(successor.first->getArgumentTypes()); + for (BlockArgument arg : successor.first->getArguments()) + dummyBlock->addArgument(arg.getType(), arg.getLoc()); builder.create(terminator->getLoc(), dummyBlock->getArguments(), successor.first); } diff --git a/mlir/lib/Dialect/Linalg/ComprehensiveBufferize/ModuleBufferization.cpp b/mlir/lib/Dialect/Linalg/ComprehensiveBufferize/ModuleBufferization.cpp --- a/mlir/lib/Dialect/Linalg/ComprehensiveBufferize/ModuleBufferization.cpp +++ b/mlir/lib/Dialect/Linalg/ComprehensiveBufferize/ModuleBufferization.cpp @@ -444,7 +444,7 @@ auto tensorType = bbArg.getType().dyn_cast(); // Non-tensor types are just forwarded. if (!tensorType) { - frontBlock.addArgument(bbArg.getType()); + frontBlock.addArgument(bbArg.getType(), bbArg.getLoc()); bbArg.replaceAllUsesWith(frontBlock.getArguments().back()); frontBlock.eraseArgument(0); continue; @@ -452,7 +452,7 @@ // Get the buffer type from the bufferized function type. Type memrefType = bufferizedFuncType.getInput(idx); - Value memref = frontBlock.addArgument(memrefType); + Value memref = frontBlock.addArgument(memrefType, bbArg.getLoc()); OpBuilder b(funcOp->getContext()); b.setInsertionPointToStart(&frontBlock); // Replace all uses of bbArg through a ToMemRefOp by a memref::CastOp. diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp --- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp +++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp @@ -128,8 +128,8 @@ auto castOp = operand.get().getDefiningOp(); if (castOp && memref::CastOp::canFoldIntoConsumerOp(castOp)) { operand.set(castOp.getOperand()); - BlockArgument newBbArg = - body->insertArgument(bbArgIndex, castOp.getOperand().getType()); + BlockArgument newBbArg = body->insertArgument( + bbArgIndex, castOp.getOperand().getType(), op.getLoc()); BlockArgument oldBbArg = body->getArgument(newBbArg.getArgNumber() + 1); // Insert memref.cast back to the original type. @@ -573,13 +573,18 @@ return; SmallVector blockArgTypes; - for (ValueRange container : {inputs, outputs}) - for (Value v : container) + SmallVector blockArgLocs; + for (ValueRange container : {inputs, outputs}) { + for (Value v : container) { blockArgTypes.push_back(getElementTypeOrSelf(v)); + blockArgLocs.push_back(v.getLoc()); + } + } OpBuilder::InsertionGuard guard(builder); auto ®ion = *result.regions.front(); - Block *bodyBlock = builder.createBlock(®ion, region.end(), blockArgTypes); + Block *bodyBlock = + builder.createBlock(®ion, region.end(), blockArgTypes, blockArgLocs); bodyBuild(builder, result.location, bodyBlock->getArguments()); } @@ -1208,13 +1213,13 @@ auto padTensorOp = builder.create(loc, type, source, low, high, nofold); int rank = padTensorOp.getResultType().getRank(); - SmallVector blockArgTypes; - blockArgTypes.assign(rank, builder.getIndexType()); + SmallVector blockArgTypes(rank, builder.getIndexType()); + SmallVector blockArgLocs(rank, loc); auto ®ion = padTensorOp.region(); // `builder.createBlock` changes the insertion point within the block. Create // a guard to reset the insertion point of the builder after it is destroyed. OpBuilder::InsertionGuard guard(builder); - builder.createBlock(®ion, region.end(), blockArgTypes); + builder.createBlock(®ion, region.end(), blockArgTypes, blockArgLocs); builder.create(loc, pad); return padTensorOp; } @@ -1770,12 +1775,17 @@ OpBuilder::InsertionGuard guard(builder); unsigned numIVs = steps.size(); SmallVector argTypes(numIVs, builder.getIndexType()); - for (Type type : TypeRange(inputs)) - argTypes.push_back(type); - for (Type type : TypeRange(outputs)) - argTypes.push_back(type); + SmallVector argLocs(numIVs, result.location); + for (Value input : inputs) { + argTypes.push_back(input.getType()); + argLocs.push_back(input.getLoc()); + } + for (Value output : outputs) { + argTypes.push_back(output.getType()); + argLocs.push_back(output.getLoc()); + } Region *bodyRegion = result.addRegion(); - Block *bodyBlock = builder.createBlock(bodyRegion, {}, argTypes); + Block *bodyBlock = builder.createBlock(bodyRegion, {}, argTypes, argLocs); if (bodyBuilderFn) { builder.setInsertionPointToStart(bodyBlock); @@ -2437,13 +2447,20 @@ // TODO: atm all operands go through getElementTypeOrSelf, // reconsider when we have evidence we need to. SmallVector argTypes; - for (auto containers : {inputTypes, outputTypes}) - for (auto t : containers) + SmallVector argLocs; + for (auto containers : {inputTypes, outputTypes}) { + for (auto t : containers) { argTypes.push_back(getElementTypeOrSelf(t)); + // TODO: Pass in a proper location here. + argLocs.push_back(opBuilder.getUnknownLoc()); + } + } + // RAII. OpBuilder::InsertionGuard guard(opBuilder); - Block *body = opBuilder.createBlock(®ion, /*insertPt=*/{}, argTypes); + Block *body = + opBuilder.createBlock(®ion, /*insertPt=*/{}, argTypes, argLocs); unsigned actual = body->getNumArguments(); unsigned expected = NamedStructuredOpType::getNumRegionArgs(); if (expected != actual) { diff --git a/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp b/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp @@ -172,7 +172,7 @@ // 3. Consumer input operands up to consumerIdx (exclusive). for (BlockArgument bbArg : consumerBlock.getArguments().take_front( consumerOpOperand->getOperandNumber())) // input assumption. - mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType())); + mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType(), bbArg.getLoc())); // Replacing consumerIdx requires getting the cloned, yielded, value from // the (cloned) producer block. This happens in step 9. @@ -180,7 +180,7 @@ // 4. Splice in producer's input operands. for (BlockArgument bbArg : producerBlock.getArguments().take_front(producer.getNumInputs())) - mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType())); + mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType(), bbArg.getLoc())); // 4.b. Producer output operand/map that is fused needs to be mapped to the // producer bbArg if it is an "initTensor" (i.e. its value is actually read). @@ -190,18 +190,18 @@ .drop_front(producer.getNumInputs()) // TODO: bbArg index of .front(); - mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType())); + mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType(), bbArg.getLoc())); } // 5. Remaining consumer's input operands (drop past index `consumerIdx`). for (BlockArgument bbArg : consumerBlock.getArguments() .take_front(consumer.getNumInputs()) .drop_front(consumerOpOperand->getOperandNumber() + 1)) - mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType())); + mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType(), bbArg.getLoc())); // 6. All of consumer's output operands. for (BlockArgument bbArg : consumerBlock.getArguments().take_back(consumer.getNumOutputs())) - mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType())); + mapper.map(bbArg, fusedBlock->addArgument(bbArg.getType(), bbArg.getLoc())); // 7. All of producer's output operands except the one fused. // TODO: allow fusion of multi-result producers. assert(producer->getNumResults() == 1 && "expected single result producer"); diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -1291,7 +1291,8 @@ OpBuilder::InsertionGuard guard(builder); unsigned numIVs = steps.size(); SmallVector argTypes(numIVs, steps.getType().front()); - builder.createBlock(bodyRegion, {}, argTypes); + SmallVector argLocs(numIVs, result.location); + builder.createBlock(bodyRegion, {}, argTypes, argLocs); } } diff --git a/mlir/lib/Dialect/PDLInterp/IR/PDLInterp.cpp b/mlir/lib/Dialect/PDLInterp/IR/PDLInterp.cpp --- a/mlir/lib/Dialect/PDLInterp/IR/PDLInterp.cpp +++ b/mlir/lib/Dialect/PDLInterp/IR/PDLInterp.cpp @@ -74,9 +74,11 @@ build(builder, state, range, successor); if (initLoop) { // Create the block and the loop variable. + // FIXME: Allow passing in a proper location for the loop variable. auto rangeType = range.getType().cast(); state.regions.front()->emplaceBlock(); - state.regions.front()->addArgument(rangeType.getElementType()); + state.regions.front()->addArgument(rangeType.getElementType(), + state.location); } } diff --git a/mlir/lib/Dialect/SCF/SCF.cpp b/mlir/lib/Dialect/SCF/SCF.cpp --- a/mlir/lib/Dialect/SCF/SCF.cpp +++ b/mlir/lib/Dialect/SCF/SCF.cpp @@ -224,7 +224,7 @@ SmallVector blockArgs; for (auto res : op.getResults()) - blockArgs.push_back(postBlock->addArgument(res.getType())); + blockArgs.push_back(postBlock->addArgument(res.getType(), res.getLoc())); rewriter.replaceOp(op, blockArgs); return success(); @@ -260,9 +260,9 @@ Region *bodyRegion = result.addRegion(); bodyRegion->push_back(new Block); Block &bodyBlock = bodyRegion->front(); - bodyBlock.addArgument(builder.getIndexType()); + bodyBlock.addArgument(builder.getIndexType(), result.location); for (Value v : iterArgs) - bodyBlock.addArgument(v.getType()); + bodyBlock.addArgument(v.getType(), v.getLoc()); // Create the default terminator if the builder is not provided and if the // iteration arguments are not provided. Otherwise, leave this to the caller @@ -1677,8 +1677,9 @@ OpBuilder::InsertionGuard guard(builder); unsigned numIVs = steps.size(); SmallVector argTypes(numIVs, builder.getIndexType()); + SmallVector argLocs(numIVs, result.location); Region *bodyRegion = result.addRegion(); - Block *bodyBlock = builder.createBlock(bodyRegion, {}, argTypes); + Block *bodyBlock = builder.createBlock(bodyRegion, {}, argTypes, argLocs); if (bodyBuilderFn) { builder.setInsertionPointToStart(bodyBlock); @@ -2054,7 +2055,8 @@ OpBuilder::InsertionGuard guard(builder); Region *bodyRegion = result.addRegion(); - Block *body = builder.createBlock(bodyRegion, {}, ArrayRef{type, type}); + Block *body = builder.createBlock(bodyRegion, {}, ArrayRef{type, type}, + {result.location, result.location}); if (bodyBuilderFn) bodyBuilderFn(builder, result.location, body->getArgument(0), body->getArgument(1)); @@ -2368,6 +2370,7 @@ SmallVector newResultsIndices; SmallVector newResultTypes; SmallVector newTermArgs; + SmallVector newArgLocs; bool needUpdate = false; for (const auto &it : llvm::enumerate(llvm::zip(op.getResults(), afterArgs, termArgs))) { @@ -2381,6 +2384,7 @@ newResultsIndices.emplace_back(i); newTermArgs.emplace_back(termArg); newResultTypes.emplace_back(result.getType()); + newArgLocs.emplace_back(result.getLoc()); } } @@ -2398,7 +2402,7 @@ rewriter.create(op.getLoc(), newResultTypes, op.getInits()); Block &newAfterBlock = *rewriter.createBlock( - &newWhile.getAfter(), /*insertPt*/ {}, newResultTypes); + &newWhile.getAfter(), /*insertPt*/ {}, newResultTypes, newArgLocs); // Build new results list and new after block args (unused entries will be // null). diff --git a/mlir/lib/Dialect/SCF/Transforms/ForToWhile.cpp b/mlir/lib/Dialect/SCF/Transforms/ForToWhile.cpp --- a/mlir/lib/Dialect/SCF/Transforms/ForToWhile.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/ForToWhile.cpp @@ -33,10 +33,14 @@ PatternRewriter &rewriter) const override { // Generate type signature for the loop-carried values. The induction // variable is placed first, followed by the forOp.iterArgs. - SmallVector lcvTypes; + SmallVector lcvTypes; + SmallVector lcvLocs; lcvTypes.push_back(forOp.getInductionVar().getType()); - llvm::transform(forOp.getInitArgs(), std::back_inserter(lcvTypes), - [&](auto v) { return v.getType(); }); + lcvLocs.push_back(forOp.getInductionVar().getLoc()); + for (Value value : forOp.getInitArgs()) { + lcvTypes.push_back(value.getType()); + lcvLocs.push_back(value.getLoc()); + } // Build scf.WhileOp SmallVector initArgs; @@ -48,7 +52,7 @@ // 'before' region contains the loop condition and forwarding of iteration // arguments to the 'after' region. auto *beforeBlock = rewriter.createBlock( - &whileOp.getBefore(), whileOp.getBefore().begin(), lcvTypes, {}); + &whileOp.getBefore(), whileOp.getBefore().begin(), lcvTypes, lcvLocs); rewriter.setInsertionPointToStart(&whileOp.getBefore().front()); auto cmpOp = rewriter.create( whileOp.getLoc(), arith::CmpIPredicate::slt, @@ -60,7 +64,7 @@ // region. The return type of the execRegionOp does not contain the // iv - yields in the source for-loop contain only iterArgs. auto *afterBlock = rewriter.createBlock( - &whileOp.getAfter(), whileOp.getAfter().begin(), lcvTypes, {}); + &whileOp.getAfter(), whileOp.getAfter().begin(), lcvTypes, lcvLocs); // Add induction variable incrementation rewriter.setInsertionPointToEnd(afterBlock); diff --git a/mlir/lib/Dialect/SCF/Transforms/Utils.cpp b/mlir/lib/Dialect/SCF/Transforms/Utils.cpp --- a/mlir/lib/Dialect/SCF/Transforms/Utils.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/Utils.cpp @@ -106,11 +106,18 @@ ValueRange outlinedValues(captures.getArrayRef()); SmallVector outlinedFuncArgTypes; + SmallVector outlinedFuncArgLocs; // Region's arguments are exactly the first block's arguments as per // Region::getArguments(). // Func's arguments are cat(regions's arguments, captures arguments). - llvm::append_range(outlinedFuncArgTypes, region.getArgumentTypes()); - llvm::append_range(outlinedFuncArgTypes, outlinedValues.getTypes()); + for (BlockArgument arg : region.getArguments()) { + outlinedFuncArgTypes.push_back(arg.getType()); + outlinedFuncArgLocs.push_back(arg.getLoc()); + } + for (Value value : outlinedValues) { + outlinedFuncArgTypes.push_back(value.getType()); + outlinedFuncArgLocs.push_back(value.getLoc()); + } FunctionType outlinedFuncType = FunctionType::get(rewriter.getContext(), outlinedFuncArgTypes, originalTerminator->getOperandTypes()); @@ -137,7 +144,9 @@ // terminator(call_results). Block *newBlock = rewriter.createBlock( ®ion, region.begin(), - TypeRange{outlinedFuncArgTypes}.take_front(numOriginalBlockArguments)); + TypeRange{outlinedFuncArgTypes}.take_front(numOriginalBlockArguments), + ArrayRef(outlinedFuncArgLocs) + .take_front(numOriginalBlockArguments)); { OpBuilder::InsertionGuard g(rewriter); rewriter.setInsertionPointToEnd(newBlock); diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp --- a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp +++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp @@ -1947,7 +1947,7 @@ SmallVector resultAttrs; SmallVector argTypes; SmallVector resultTypes; - SmallVector> argLocations; + SmallVector argLocations; auto &builder = parser.getBuilder(); // Parse the name as a symbol. diff --git a/mlir/lib/Dialect/Shape/IR/Shape.cpp b/mlir/lib/Dialect/Shape/IR/Shape.cpp --- a/mlir/lib/Dialect/Shape/IR/Shape.cpp +++ b/mlir/lib/Dialect/Shape/IR/Shape.cpp @@ -1625,18 +1625,18 @@ Region *bodyRegion = result.addRegion(); bodyRegion->push_back(new Block); Block &bodyBlock = bodyRegion->front(); - bodyBlock.addArgument(builder.getIndexType()); + bodyBlock.addArgument(builder.getIndexType(), result.location); Type elementType; if (auto tensorType = shape.getType().dyn_cast()) elementType = tensorType.getElementType(); else elementType = SizeType::get(builder.getContext()); - bodyBlock.addArgument(elementType); + bodyBlock.addArgument(elementType, shape.getLoc()); - for (Type initValType : initVals.getTypes()) { - bodyBlock.addArgument(initValType); - result.addTypes(initValType); + for (Value initVal : initVals) { + bodyBlock.addArgument(initVal.getType(), initVal.getLoc()); + result.addTypes(initVal.getType()); } } diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp --- a/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp @@ -1204,8 +1204,10 @@ assert(types.size() == operands.size()); Location loc = op.getLoc(); scf::WhileOp whileOp = rewriter.create(loc, types, operands); - Block *before = rewriter.createBlock(&whileOp.getBefore(), {}, types); - Block *after = rewriter.createBlock(&whileOp.getAfter(), {}, types); + + SmallVector locs(types.size(), loc); + Block *before = rewriter.createBlock(&whileOp.getBefore(), {}, types, locs); + Block *after = rewriter.createBlock(&whileOp.getAfter(), {}, types, locs); // Build the "before" region, which effectively consists // of a conjunction of "i < upper" tests on all induction. diff --git a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -146,7 +146,7 @@ Region *bodyRegion = result.addRegion(); bodyRegion->push_back(new Block()); - bodyRegion->addArgument(elementType); + bodyRegion->addArgument(elementType, memref.getLoc()); } } diff --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp --- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp +++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp @@ -495,8 +495,9 @@ Region *bodyRegion = result.regions.front().get(); auto rank = resultTy.cast().getRank(); SmallVector argumentTypes(rank, b.getIndexType()); + SmallVector argumentLocs(rank, result.location); Block *bodyBlock = - b.createBlock(bodyRegion, bodyRegion->end(), argumentTypes); + b.createBlock(bodyRegion, bodyRegion->end(), argumentTypes, argumentLocs); bodyBuilder(b, result.location, bodyBlock->getArguments()); } diff --git a/mlir/lib/IR/Block.cpp b/mlir/lib/IR/Block.cpp --- a/mlir/lib/IR/Block.cpp +++ b/mlir/lib/IR/Block.cpp @@ -138,17 +138,8 @@ return ValueTypeRange(getArguments()); } -BlockArgument Block::addArgument(Type type, Optional loc) { - // TODO: Require locations for BlockArguments. - if (!loc.hasValue()) { - // Use the location of the parent operation if the block is attached. - if (Operation *parentOp = getParentOp()) - loc = parentOp->getLoc(); - else - loc = UnknownLoc::get(type.getContext()); - } - - BlockArgument arg = BlockArgument::create(type, this, arguments.size(), *loc); +BlockArgument Block::addArgument(Type type, Location loc) { + BlockArgument arg = BlockArgument::create(type, this, arguments.size(), loc); arguments.push_back(arg); return arg; } @@ -156,37 +147,20 @@ /// Add one argument to the argument list for each type specified in the list. auto Block::addArguments(TypeRange types, ArrayRef locs) -> iterator_range { - // TODO: Require locations for BlockArguments. - assert((locs.empty() || types.size() == locs.size()) && + assert(types.size() == locs.size() && "incorrect number of block argument locations"); size_t initialSize = arguments.size(); - arguments.reserve(initialSize + types.size()); - // TODO: Require locations for BlockArguments. - if (locs.empty()) { - for (auto type : types) - addArgument(type); - } else { - for (auto typeAndLoc : llvm::zip(types, locs)) - addArgument(std::get<0>(typeAndLoc), std::get<1>(typeAndLoc)); - } + for (auto typeAndLoc : llvm::zip(types, locs)) + addArgument(std::get<0>(typeAndLoc), std::get<1>(typeAndLoc)); return {arguments.data() + initialSize, arguments.data() + arguments.size()}; } -BlockArgument Block::insertArgument(unsigned index, Type type, - Optional loc) { - // TODO: Require locations for BlockArguments. - if (!loc.hasValue()) { - // Use the location of the parent operation if the block is attached. - if (Operation *parentOp = getParentOp()) - loc = parentOp->getLoc(); - else - loc = UnknownLoc::get(type.getContext()); - } +BlockArgument Block::insertArgument(unsigned index, Type type, Location loc) { + assert(index <= arguments.size() && "invalid insertion index"); - auto arg = BlockArgument::create(type, this, index, *loc); - assert(index <= arguments.size()); + auto arg = BlockArgument::create(type, this, index, loc); arguments.insert(arguments.begin() + index, arg); // Update the cached position for all the arguments after the newly inserted // one. @@ -198,8 +172,7 @@ /// Insert one value to the given position of the argument list. The existing /// arguments are shifted. The block is expected not to have predecessors. -BlockArgument Block::insertArgument(args_iterator it, Type type, - Optional loc) { +BlockArgument Block::insertArgument(args_iterator it, Type type, Location loc) { assert(llvm::empty(getPredecessors()) && "cannot insert arguments to blocks with predecessors"); return insertArgument(it->getArgNumber(), type, loc); diff --git a/mlir/lib/IR/Builders.cpp b/mlir/lib/IR/Builders.cpp --- a/mlir/lib/IR/Builders.cpp +++ b/mlir/lib/IR/Builders.cpp @@ -350,12 +350,10 @@ return op; } -/// Add new block with 'argTypes' arguments and set the insertion point to the -/// end of it. The block is inserted at the provided insertion point of -/// 'parent'. Block *OpBuilder::createBlock(Region *parent, Region::iterator insertPt, TypeRange argTypes, ArrayRef locs) { assert(parent && "expected valid parent region"); + assert(argTypes.size() == locs.size() && "argument location mismatch"); if (insertPt == Region::iterator()) insertPt = parent->end(); diff --git a/mlir/lib/IR/FunctionImplementation.cpp b/mlir/lib/IR/FunctionImplementation.cpp --- a/mlir/lib/IR/FunctionImplementation.cpp +++ b/mlir/lib/IR/FunctionImplementation.cpp @@ -17,7 +17,7 @@ OpAsmParser &parser, bool allowAttributes, bool allowVariadic, SmallVectorImpl &argNames, SmallVectorImpl &argTypes, SmallVectorImpl &argAttrs, - SmallVectorImpl> &argLocations, bool &isVariadic) { + SmallVectorImpl &argLocations, bool &isVariadic) { if (parser.parseLParen()) return failure(); @@ -65,7 +65,9 @@ if (!argument.name.empty() && parser.parseOptionalLocationSpecifier(explicitLoc)) return failure(); - argLocations.push_back(explicitLoc); + if (!explicitLoc) + explicitLoc = parser.getEncodedSourceLoc(loc); + argLocations.push_back(*explicitLoc); return success(); }; @@ -133,7 +135,7 @@ OpAsmParser &parser, bool allowVariadic, SmallVectorImpl &argNames, SmallVectorImpl &argTypes, SmallVectorImpl &argAttrs, - SmallVectorImpl> &argLocations, bool &isVariadic, + SmallVectorImpl &argLocations, bool &isVariadic, SmallVectorImpl &resultTypes, SmallVectorImpl &resultAttrs) { bool allowArgAttrs = true; @@ -197,7 +199,7 @@ SmallVector resultAttrs; SmallVector argTypes; SmallVector resultTypes; - SmallVector> argLocations; + SmallVector argLocations; auto &builder = parser.getBuilder(); // Parse visibility. @@ -257,7 +259,7 @@ llvm::SMLoc loc = parser.getCurrentLocation(); OptionalParseResult parseResult = parser.parseOptionalRegion( *body, entryArgs, entryArgs.empty() ? ArrayRef() : argTypes, - entryArgs.empty() ? ArrayRef>() : argLocations, + entryArgs.empty() ? ArrayRef() : argLocations, /*enableNameShadowing=*/false); if (parseResult.hasValue()) { if (failed(*parseResult)) diff --git a/mlir/lib/IR/FunctionInterfaces.cpp b/mlir/lib/IR/FunctionInterfaces.cpp --- a/mlir/lib/IR/FunctionInterfaces.cpp +++ b/mlir/lib/IR/FunctionInterfaces.cpp @@ -130,11 +130,11 @@ void mlir::function_interface_impl::insertFunctionArguments( Operation *op, ArrayRef argIndices, TypeRange argTypes, - ArrayRef argAttrs, ArrayRef> argLocs, + ArrayRef argAttrs, ArrayRef argLocs, unsigned originalNumArgs, Type newType) { assert(argIndices.size() == argTypes.size()); assert(argIndices.size() == argAttrs.size() || argAttrs.empty()); - assert(argIndices.size() == argLocs.size() || argLocs.empty()); + assert(argIndices.size() == argLocs.size()); if (argIndices.empty()) return; @@ -171,8 +171,7 @@ // Update the function type and any entry block arguments. op->setAttr(getTypeAttrName(), TypeAttr::get(newType)); for (unsigned i = 0, e = argIndices.size(); i < e; ++i) - entry.insertArgument(argIndices[i] + i, argTypes[i], - argLocs.empty() ? Optional{} : argLocs[i]); + entry.insertArgument(argIndices[i] + i, argTypes[i], argLocs[i]); } void mlir::function_interface_impl::insertFunctionResults( diff --git a/mlir/lib/IR/Region.cpp b/mlir/lib/IR/Region.cpp --- a/mlir/lib/IR/Region.cpp +++ b/mlir/lib/IR/Region.cpp @@ -33,14 +33,13 @@ return container->getLoc(); } -/// Return a range containing the types of the arguments for this region. auto Region::getArgumentTypes() -> ValueTypeRange { return ValueTypeRange(getArguments()); } -/// Add one argument to the argument list for each type specified in the list. -iterator_range Region::addArguments(TypeRange types) { - return front().addArguments(types); +iterator_range +Region::addArguments(TypeRange types, ArrayRef locs) { + return front().addArguments(types, locs); } Region *Region::getParentRegion() { diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -368,15 +368,14 @@ /// region is isolated from those above. ParseResult parseRegion(Region ®ion, ArrayRef> entryArguments, - ArrayRef> argLocations = {}, + ArrayRef argLocations, bool isIsolatedNameScope = false); /// Parse a region body into 'region'. ParseResult parseRegionBody(Region ®ion, llvm::SMLoc startLoc, ArrayRef> entryArguments, - ArrayRef> argLocations, - bool isIsolatedNameScope); + ArrayRef argLocations, bool isIsolatedNameScope); //===--------------------------------------------------------------------===// // Block Parsing @@ -1055,7 +1054,8 @@ do { // Create temporary regions with the top level region as parent. result.regions.emplace_back(new Region(topLevelOp)); - if (parseRegion(*result.regions.back(), /*entryArguments=*/{})) + if (parseRegion(*result.regions.back(), /*entryArguments=*/{}, + /*argLocations=*/{})) return failure(); } while (consumeIf(Token::comma)); if (parseToken(Token::r_paren, "expected ')' to end region list")) @@ -1451,7 +1451,7 @@ /// effectively defines the SSA values of `arguments` and assigns their type. ParseResult parseRegion(Region ®ion, ArrayRef arguments, ArrayRef argTypes, - ArrayRef> argLocations, + ArrayRef argLocations, bool enableNameShadowing) override { assert(arguments.size() == argTypes.size() && "mismatching number of arguments and types"); @@ -1477,11 +1477,11 @@ } /// Parses a region if present. - OptionalParseResult - parseOptionalRegion(Region ®ion, ArrayRef arguments, - ArrayRef argTypes, - ArrayRef> argLocations, - bool enableNameShadowing) override { + OptionalParseResult parseOptionalRegion(Region ®ion, + ArrayRef arguments, + ArrayRef argTypes, + ArrayRef argLocations, + bool enableNameShadowing) override { if (parser.getToken().isNot(Token::l_brace)) return llvm::None; return parseRegion(region, arguments, argTypes, argLocations, @@ -1823,7 +1823,7 @@ ParseResult OperationParser::parseRegion( Region ®ion, ArrayRef> entryArguments, - ArrayRef> argLocations, bool isIsolatedNameScope) { + ArrayRef argLocations, bool isIsolatedNameScope) { // Parse the '{'. Token lBraceTok = getToken(); if (parseToken(Token::l_brace, "expected '{' to begin a region")) @@ -1851,7 +1851,7 @@ ParseResult OperationParser::parseRegionBody( Region ®ion, llvm::SMLoc startLoc, ArrayRef> entryArguments, - ArrayRef> argLocations, bool isIsolatedNameScope) { + ArrayRef argLocations, bool isIsolatedNameScope) { assert(argLocations.empty() || argLocations.size() == entryArguments.size()); auto currentPt = opBuilder.saveInsertionPoint(); @@ -1886,11 +1886,11 @@ .attachNote(getEncodedSourceLocation(*defLoc)) << "previously referenced here"; } - Location loc = - (!argLocations.empty() && argLocations[argIndex]) - ? *argLocations[argIndex] - : getEncodedSourceLocation(placeholderArgPair.first.loc); - BlockArgument arg = block->addArgument(placeholderArgPair.second, loc); + BlockArgument arg = block->addArgument( + placeholderArgPair.second, + argLocations.empty() + ? getEncodedSourceLocation(placeholderArgPair.first.loc) + : argLocations[argIndex]); // Add a definition of this arg to the assembly state if provided. if (state.asmState) 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 @@ -647,7 +647,8 @@ Type type = processType(inst->getType()); if (!type) return failure(); - v = b.getInsertionBlock()->addArgument(type); + v = b.getInsertionBlock()->addArgument( + type, processDebugLoc(inst->getDebugLoc(), inst)); return success(); } case llvm::Instruction::Call: { @@ -822,9 +823,10 @@ currentEntryBlock = blockList[0]; // 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())); + for (const auto &kv : llvm::enumerate(f->args())) { + instMap[&kv.value()] = blockList[0]->addArgument( + functionType.getParamType(kv.index()), fop.getLoc()); + } for (auto bbs : llvm::zip(*f, blockList)) { if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp --- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp +++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp @@ -1580,7 +1580,7 @@ // Create a block argument for this OpPhi instruction. Type blockArgType = getType(operands[0]); - BlockArgument blockArg = curBlock->addArgument(blockArgType); + BlockArgument blockArg = curBlock->addArgument(blockArgType, unknownLoc); valueMap[operands[1]] = blockArg; LLVM_DEBUG(logger.startLine() << "[phi] created block argument " << blockArg @@ -1748,7 +1748,8 @@ << " from block " << block << "\n"); if (!isFnEntryBlock(block)) { for (BlockArgument blockArg : block->getArguments()) { - auto newArg = newBlock->addArgument(blockArg.getType()); + auto newArg = + newBlock->addArgument(blockArg.getType(), blockArg.getLoc()); mapper.map(blockArg, newArg); LLVM_DEBUG(logger.startLine() << "[cf] remapped block argument " << blockArg << " to " << newArg << "\n"); @@ -1797,9 +1798,8 @@ // The loop header block may have block arguments. Since now we place the // loop op inside the old merge block, we need to make sure the old merge // block has the same block argument list. - for (BlockArgument blockArg : headerBlock->getArguments()) { - mergeBlock->addArgument(blockArg.getType()); - } + for (BlockArgument blockArg : headerBlock->getArguments()) + mergeBlock->addArgument(blockArg.getType(), blockArg.getLoc()); // If the loop header block has block arguments, make sure the spv.Branch op // matches. diff --git a/mlir/lib/Transforms/BufferResultsToOutParams.cpp b/mlir/lib/Transforms/BufferResultsToOutParams.cpp --- a/mlir/lib/Transforms/BufferResultsToOutParams.cpp +++ b/mlir/lib/Transforms/BufferResultsToOutParams.cpp @@ -50,8 +50,9 @@ // Add the new arguments to the entry block if the function is not external. if (func.isExternal()) return; - auto newArgs = func.front().addArguments(erasedResultTypes); - appendedEntryArgs.append(newArgs.begin(), newArgs.end()); + Location loc = func.getLoc(); + for (Type type : erasedResultTypes) + appendedEntryArgs.push_back(func.front().addArgument(type, loc)); } // Updates all ReturnOps in the scope of the given FuncOp by either keeping them diff --git a/mlir/lib/Transforms/NormalizeMemRefs.cpp b/mlir/lib/Transforms/NormalizeMemRefs.cpp --- a/mlir/lib/Transforms/NormalizeMemRefs.cpp +++ b/mlir/lib/Transforms/NormalizeMemRefs.cpp @@ -332,6 +332,8 @@ OpBuilder b(funcOp); FunctionType functionType = funcOp.getType(); + SmallVector functionArgLocs(llvm::map_range( + funcOp.getArguments(), [](BlockArgument arg) { return arg.getLoc(); })); SmallVector inputTypes; // Walk over each argument of a function to perform memref normalization (if for (unsigned argIndex : @@ -356,8 +358,8 @@ } // Insert a new temporary argument with the new memref type. - BlockArgument newMemRef = - funcOp.front().insertArgument(argIndex, newMemRefType); + BlockArgument newMemRef = funcOp.front().insertArgument( + argIndex, newMemRefType, functionArgLocs[argIndex]); BlockArgument oldMemRef = funcOp.getArgument(argIndex + 1); AffineMap layoutMap = memrefType.getLayout().getAffineMap(); // Replace all uses of the old memref. diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -763,7 +763,11 @@ Block *newBlock = block->splitBlock(block->begin()); block->replaceAllUsesWith(newBlock); - SmallVector newArgRange(newBlock->addArguments(convertedTypes)); + // FIXME: We should map the new arguments to proper locations. + SmallVector newLocs(convertedTypes.size(), + rewriter.getUnknownLoc()); + SmallVector newArgRange( + newBlock->addArguments(convertedTypes, newLocs)); ArrayRef newArgs(newArgRange); // Remap each of the original arguments as determined by the signature diff --git a/mlir/lib/Transforms/Utils/InliningUtils.cpp b/mlir/lib/Transforms/Utils/InliningUtils.cpp --- a/mlir/lib/Transforms/Utils/InliningUtils.cpp +++ b/mlir/lib/Transforms/Utils/InliningUtils.cpp @@ -216,8 +216,9 @@ // Otherwise, there were multiple blocks inlined. Add arguments to the post // insertion block to represent the results to replace. for (const auto &resultToRepl : llvm::enumerate(resultsToReplace)) { - resultToRepl.value().replaceAllUsesWith(postInsertBlock->addArgument( - regionResultTypes[resultToRepl.index()])); + resultToRepl.value().replaceAllUsesWith( + postInsertBlock->addArgument(regionResultTypes[resultToRepl.index()], + resultToRepl.value().getLoc())); } /// Handle the terminators for each of the new blocks. diff --git a/mlir/lib/Transforms/Utils/RegionUtils.cpp b/mlir/lib/Transforms/Utils/RegionUtils.cpp --- a/mlir/lib/Transforms/Utils/RegionUtils.cpp +++ b/mlir/lib/Transforms/Utils/RegionUtils.cpp @@ -601,8 +601,11 @@ newArguments[i][it.index()] = operand.get(); // Update the operand and insert an argument if this is the leader. - if (i == 0) - operand.set(leaderBlock->addArgument(operand.get().getType())); + if (i == 0) { + Value operandVal = operand.get(); + operand.set(leaderBlock->addArgument(operandVal.getType(), + operandVal.getLoc())); + } } } // Update the predecessors for each of the blocks. diff --git a/mlir/test/CAPI/ir.c b/mlir/test/CAPI/ir.c --- a/mlir/test/CAPI/ir.c +++ b/mlir/test/CAPI/ir.c @@ -81,9 +81,11 @@ MlirType memrefType = mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref")); MlirType funcBodyArgTypes[] = {memrefType, memrefType}; + MlirLocation funcBodyArgLocs[] = {location, location}; MlirRegion funcBodyRegion = mlirRegionCreate(); - MlirBlock funcBody = mlirBlockCreate( - sizeof(funcBodyArgTypes) / sizeof(MlirType), funcBodyArgTypes); + MlirBlock funcBody = + mlirBlockCreate(sizeof(funcBodyArgTypes) / sizeof(MlirType), + funcBodyArgTypes, funcBodyArgLocs); mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody); MlirAttribute funcTypeAttr = mlirAttributeParseGet( @@ -130,8 +132,8 @@ mlirBlockAppendOwnedOperation(funcBody, dim); MlirRegion loopBodyRegion = mlirRegionCreate(); - MlirBlock loopBody = mlirBlockCreate(0, NULL); - mlirBlockAddArgument(loopBody, indexType); + MlirBlock loopBody = mlirBlockCreate(0, NULL, NULL); + mlirBlockAddArgument(loopBody, indexType, location); mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody); MlirAttribute indexOneLiteral = @@ -507,10 +509,10 @@ MlirType i2 = mlirIntegerTypeGet(ctx, 2); MlirType i3 = mlirIntegerTypeGet(ctx, 3); MlirType i4 = mlirIntegerTypeGet(ctx, 4); - MlirBlock block1 = mlirBlockCreate(1, &i1); - MlirBlock block2 = mlirBlockCreate(1, &i2); - MlirBlock block3 = mlirBlockCreate(1, &i3); - MlirBlock block4 = mlirBlockCreate(1, &i4); + MlirBlock block1 = mlirBlockCreate(1, &i1, &loc); + MlirBlock block2 = mlirBlockCreate(1, &i2, &loc); + MlirBlock block3 = mlirBlockCreate(1, &i3, &loc); + MlirBlock block4 = mlirBlockCreate(1, &i4, &loc); // Insert blocks so as to obtain the 1-2-3-4 order, mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3); mlirRegionInsertOwnedBlockBefore(region, block3, block2); @@ -1549,7 +1551,7 @@ MlirOperationState opState = mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc); MlirRegion region = mlirRegionCreate(); - MlirBlock block = mlirBlockCreate(0, NULL); + MlirBlock block = mlirBlockCreate(0, NULL, NULL); mlirRegionAppendOwnedBlock(region, block); mlirOperationStateAddOwnedRegions(&opState, 1, ®ion); MlirOperation op = mlirOperationCreate(&opState); diff --git a/mlir/test/lib/Dialect/Test/TestPatterns.cpp b/mlir/test/lib/Dialect/Test/TestPatterns.cpp --- a/mlir/test/lib/Dialect/Test/TestPatterns.cpp +++ b/mlir/test/lib/Dialect/Test/TestPatterns.cpp @@ -297,7 +297,8 @@ newRegion.addRegion(); auto *regionOp = rewriter.createOperation(newRegion); auto *entryBlock = rewriter.createBlock(®ionOp->getRegion(0)); - entryBlock->addArgument(rewriter.getIntegerType(64)); + entryBlock->addArgument(rewriter.getIntegerType(64), + rewriter.getUnknownLoc()); // Add an explicitly illegal operation to ensure the conversion fails. rewriter.create(op->getLoc(), rewriter.getIntegerType(32)); @@ -318,8 +319,9 @@ PatternRewriter &rewriter) const final { Region ®ion = *op->getParentRegion(); Type i32Type = rewriter.getIntegerType(32); - rewriter.createBlock(®ion, region.end(), {i32Type, i32Type}); - rewriter.create(op->getLoc()); + Location loc = op->getLoc(); + rewriter.createBlock(®ion, region.end(), {i32Type, i32Type}, {loc, loc}); + rewriter.create(loc); rewriter.replaceOp(op, {}); return success(); } @@ -335,10 +337,11 @@ PatternRewriter &rewriter) const final { Region ®ion = *op->getParentRegion(); Type i32Type = rewriter.getIntegerType(32); - rewriter.createBlock(®ion, region.end(), {i32Type, i32Type}); + Location loc = op->getLoc(); + rewriter.createBlock(®ion, region.end(), {i32Type, i32Type}, {loc, loc}); // Create an illegal op to ensure the conversion fails. - rewriter.create(op->getLoc(), i32Type); - rewriter.create(op->getLoc()); + rewriter.create(loc, i32Type); + rewriter.create(loc); rewriter.replaceOp(op, {}); return success(); } diff --git a/mlir/test/lib/IR/TestFunc.cpp b/mlir/test/lib/IR/TestFunc.cpp --- a/mlir/test/lib/IR/TestFunc.cpp +++ b/mlir/test/lib/IR/TestFunc.cpp @@ -20,6 +20,7 @@ void runOnOperation() override { auto module = getOperation(); + UnknownLoc unknownLoc = UnknownLoc::get(module.getContext()); for (FuncOp func : module.getOps()) { auto inserts = func->getAttrOfType("test.insert_args"); if (!inserts || inserts.empty()) @@ -27,7 +28,7 @@ SmallVector indicesToInsert; SmallVector typesToInsert; SmallVector attrsToInsert; - SmallVector, 4> locsToInsert; + SmallVector locsToInsert; for (auto insert : inserts.getAsRange()) { indicesToInsert.push_back( insert[0].cast().getValue().getZExtValue()); @@ -35,10 +36,9 @@ attrsToInsert.push_back(insert.size() > 2 ? insert[2].cast() : DictionaryAttr::get(&getContext())); - locsToInsert.push_back( - insert.size() > 3 - ? Optional(insert[3].cast()) - : Optional{}); + locsToInsert.push_back(insert.size() > 3 + ? Location(insert[3].cast()) + : unknownLoc); } func->removeAttr("test.insert_args"); func.insertArguments(indicesToInsert, typesToInsert, attrsToInsert,