// Utility to print an LLVM value as a string for passing to emitError().
// FIXME: Diagnostic should be able to natively handle types that have
// operator << (raw_ostream&) defined.
-static std::string diag(llvm::Value &v) {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << v;
+static std::string diag(llvm::Value &value) {
+ std::string str;
+ llvm::raw_string_ostream os(str);
+ os << value;
return os.str();
}
}
}
-static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) {
- switch (p) {
+static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate pred) {
+ switch (pred) {
default:
llvm_unreachable("incorrect comparison predicate");
case llvm::CmpInst::Predicate::ICMP_EQ:
llvm_unreachable("incorrect integer comparison predicate");
}
-static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate p) {
- switch (p) {
+static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate pred) {
+ switch (pred) {
default:
llvm_unreachable("incorrect comparison predicate");
case llvm::CmpInst::Predicate::FCMP_FALSE:
class Importer {
public:
Importer(MLIRContext *context, ModuleOp module)
- : b(context), context(context), module(module), typeTranslator(*context) {
- b.setInsertionPointToStart(module.getBody());
+ : builder(context), context(context), module(module),
+ typeTranslator(*context) {
+ builder.setInsertionPointToStart(module.getBody());
}
/// Stores the mapping between an LLVM value and its MLIR counterpart.
LogicalResult convertOperation(OpBuilder &odsBuilder,
llvm::Instruction *inst);
- /// Imports `f` into the current module.
- LogicalResult processFunction(llvm::Function *f);
+ /// Imports `func` into the current module.
+ LogicalResult processFunction(llvm::Function *func);
- /// Converts function attributes of LLVM Function \p f
+ /// Converts function attributes of LLVM Function \p func
/// into LLVM dialect attributes of LLVMFuncOp \p funcOp.
- void processFunctionAttributes(llvm::Function *f, LLVMFuncOp funcOp);
+ void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp);
/// Imports GV as a GlobalOp, creating it if it doesn't exist.
GlobalOp processGlobal(llvm::GlobalVariable *gv);
private:
- /// Returns personality of `f` as a FlatSymbolRefAttr.
- FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *f);
+ /// Returns personality of `func` as a FlatSymbolRefAttr.
+ FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *func);
/// Imports `bb` into `block`, which must be initially empty.
LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block);
/// Imports `inst` and populates valueMapping[inst] with the result of the
Type getStdTypeForAttr(Type type);
/// Return `value` as an attribute to attach to a GlobalOp.
Attribute getConstantAsAttr(llvm::Constant *value);
- /// Return `c` as an MLIR Value. This could either be a ConstantOp, or
+ /// Return `constant` as an MLIR Value. This could either be a ConstantOp, or
/// an expanded sequence of ops in the current function's entry block (for
/// ConstantExprs or ConstantGEPs).
- Value processConstant(llvm::Constant *c);
+ Value processConstant(llvm::Constant *constant);
- /// The current builder, pointing at where the next Instruction should be
- /// generated.
- OpBuilder b;
+ /// Builder pointing at where the next Instruction should be generated.
+ OpBuilder builder;
/// The current context.
MLIRContext *context;
/// The current module being created.
/// Globals are inserted before the first function, if any.
Block::iterator getGlobalInsertPt() {
- auto it = module.getBody()->begin();
- auto endIt = module.getBody()->end();
+ Block::iterator it = module.getBody()->begin();
+ Block::iterator endIt = module.getBody()->end();
while (it != endIt && !isa<LLVMFuncOp>(it))
++it;
return it;
// LLVM vectors can only contain scalars.
if (LLVM::isCompatibleVectorType(type)) {
- auto numElements = LLVM::getVectorNumElements(type);
+ llvm::ElementCount numElements = LLVM::getVectorNumElements(type);
if (numElements.isScalable()) {
emitError(UnknownLoc::get(context)) << "scalable vectors not supported";
return nullptr;
// If the innermost type is a vector, use the multi-dimensional vector as
// attribute type.
if (LLVM::isCompatibleVectorType(arrayType.getElementType())) {
- auto numElements = LLVM::getVectorNumElements(arrayType.getElementType());
+ llvm::ElementCount numElements =
+ LLVM::getVectorNumElements(arrayType.getElementType());
if (numElements.isScalable()) {
emitError(UnknownLoc::get(context)) << "scalable vectors not supported";
return nullptr;
// as attributes.
Attribute Importer::getConstantAsAttr(llvm::Constant *value) {
if (auto *ci = dyn_cast<llvm::ConstantInt>(value))
- return b.getIntegerAttr(
+ return builder.getIntegerAttr(
IntegerType::get(context, ci->getType()->getBitWidth()),
ci->getValue());
if (auto *c = dyn_cast<llvm::ConstantDataArray>(value))
if (c->isString())
- return b.getStringAttr(c->getAsString());
+ return builder.getStringAttr(c->getAsString());
if (auto *c = dyn_cast<llvm::ConstantFP>(value)) {
- auto *type = c->getType();
+ llvm::Type *type = c->getType();
FloatType floatTy;
if (type->isBFloatTy())
floatTy = FloatType::getBF16(context);
else
floatTy = getDLFloatType(*context, type->getScalarSizeInBits());
assert(floatTy && "unsupported floating point type");
- return b.getFloatAttr(floatTy, c->getValueAPF());
+ return builder.getFloatAttr(floatTy, c->getValueAPF());
}
if (auto *f = dyn_cast<llvm::Function>(value))
- return SymbolRefAttr::get(b.getContext(), f->getName());
+ return SymbolRefAttr::get(builder.getContext(), f->getName());
// Convert constant data to a dense elements attribute.
if (auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) {
return globals[gv] = op;
}
-Value Importer::processConstant(llvm::Constant *c) {
+Value Importer::processConstant(llvm::Constant *constant) {
OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin());
- if (Attribute attr = getConstantAsAttr(c)) {
+ if (Attribute attr = getConstantAsAttr(constant)) {
// These constants can be represented as attributes.
OpBuilder b(currentEntryBlock, currentEntryBlock->begin());
- Type type = convertType(c->getType());
+ Type type = convertType(constant->getType());
if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>())
return bEntry.create<AddressOfOp>(UnknownLoc::get(context), type,
symbolRef.getValue());
return bEntry.create<ConstantOp>(UnknownLoc::get(context), type, attr);
}
- if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) {
+ if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(constant)) {
Type type = convertType(cn->getType());
return bEntry.create<NullOp>(UnknownLoc::get(context), type);
}
- if (auto *gv = dyn_cast<llvm::GlobalVariable>(c))
+ if (auto *gv = dyn_cast<llvm::GlobalVariable>(constant))
return bEntry.create<AddressOfOp>(UnknownLoc::get(context),
processGlobal(gv));
- if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) {
+ if (auto *ce = dyn_cast<llvm::ConstantExpr>(constant)) {
llvm::Instruction *i = ce->getAsInstruction();
- OpBuilder::InsertionGuard guard(b);
- b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
+ OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
if (failed(processInstruction(i)))
return nullptr;
assert(valueMapping.count(i));
i->deleteValue();
return value;
}
- if (auto *ue = dyn_cast<llvm::UndefValue>(c)) {
+ if (auto *ue = dyn_cast<llvm::UndefValue>(constant)) {
Type type = convertType(ue->getType());
return bEntry.create<UndefOp>(UnknownLoc::get(context), type);
}
- if (isa<llvm::ConstantAggregate>(c) || isa<llvm::ConstantAggregateZero>(c)) {
- unsigned numElements = c->getNumOperands();
+ if (isa<llvm::ConstantAggregate>(constant) ||
+ isa<llvm::ConstantAggregateZero>(constant)) {
+ unsigned numElements = constant->getNumOperands();
std::function<llvm::Constant *(unsigned)> getElement =
[&](unsigned index) -> llvm::Constant * {
- return c->getAggregateElement(index);
+ return constant->getAggregateElement(index);
};
// llvm::ConstantAggregateZero doesn't take any operand
// so its getNumOperands is always zero.
- if (auto *caz = dyn_cast<llvm::ConstantAggregateZero>(c)) {
+ if (auto *caz = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
numElements = caz->getElementCount().getFixedValue();
// We want to capture the pointer rather than reference
// to the pointer since the latter will become dangling upon
}
// Generate a llvm.undef as the root value first.
- Type rootType = convertType(c->getType());
+ Type rootType = convertType(constant->getType());
bool useInsertValue = rootType.isa<LLVMArrayType, LLVMStructType>();
assert((useInsertValue || LLVM::isCompatibleVectorType(rootType)) &&
"unrecognized aggregate type");
return root;
}
- emitError(UnknownLoc::get(context)) << "unhandled constant: " << diag(*c);
+ emitError(UnknownLoc::get(context))
+ << "unhandled constant: " << diag(*constant);
return nullptr;
}
// Convert all intrinsics that provide an MLIR builder.
if (auto *callInst = dyn_cast<llvm::CallInst>(inst))
- if (succeeded(convertIntrinsic(b, callInst)))
+ if (succeeded(convertIntrinsic(builder, callInst)))
return success();
// Convert all operations that provide an MLIR builder.
- if (succeeded(convertOperation(b, inst)))
+ if (succeeded(convertOperation(builder, inst)))
return success();
// Convert all special instructions that do not provide an MLIR builder.
std::array<int32_t, 3> operandSegmentSizes = {1, 0, 0};
for (int i : llvm::seq<int>(0, brInst->getNumSuccessors())) {
- auto *succ = brInst->getSuccessor(i);
+ llvm::BasicBlock *succ = brInst->getSuccessor(i);
SmallVector<Value, 4> blockArguments;
if (failed(processBranchArgs(brInst, succ, blockArguments)))
return failure();
if (brInst->isConditional()) {
state.addAttribute(LLVM::CondBrOp::getOperandSegmentSizeAttr(),
- b.getDenseI32ArrayAttr(operandSegmentSizes));
+ builder.getDenseI32ArrayAttr(operandSegmentSizes));
}
- b.create(state);
+ builder.create(state);
return success();
}
if (inst->getOpcode() == llvm::Instruction::Switch) {
SmallVector<ValueRange> caseOperandRefs(numCases);
SmallVector<int32_t> caseValues(numCases);
SmallVector<Block *> caseBlocks(numCases);
- for (const auto &en : llvm::enumerate(swInst->cases())) {
- const llvm::SwitchInst::CaseHandle &caseHandle = en.value();
- unsigned i = en.index();
+ for (const auto &it : llvm::enumerate(swInst->cases())) {
+ const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
- if (failed(processBranchArgs(swInst, succBB, caseOperands[i])))
+ if (failed(processBranchArgs(swInst, succBB, caseOperands[it.index()])))
return failure();
- caseOperandRefs[i] = caseOperands[i];
- caseValues[i] = caseHandle.getCaseValue()->getSExtValue();
- caseBlocks[i] = lookupBlock(succBB);
+ caseOperandRefs[it.index()] = caseOperands[it.index()];
+ caseValues[it.index()] = caseHandle.getCaseValue()->getSExtValue();
+ caseBlocks[it.index()] = lookupBlock(succBB);
}
- b.create<SwitchOp>(loc, condition, lookupBlock(defaultBB), defaultBlockArgs,
- caseValues, caseBlocks, caseOperandRefs);
+ builder.create<SwitchOp>(loc, condition, lookupBlock(defaultBB),
+ defaultBlockArgs, caseValues, caseBlocks,
+ caseOperandRefs);
return success();
}
if (inst->getOpcode() == llvm::Instruction::PHI) {
Type type = convertType(inst->getType());
- mapValue(inst, b.getInsertionBlock()->addArgument(
+ mapValue(inst, builder.getInsertionBlock()->addArgument(
type, translateLoc(inst->getDebugLoc())));
return success();
}
}
Operation *op;
if (llvm::Function *callee = ci->getCalledFunction()) {
- op = b.create<CallOp>(
- loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops);
+ op = builder.create<CallOp>(
+ loc, tys, SymbolRefAttr::get(builder.getContext(), callee->getName()),
+ ops);
} else {
Value calledValue = processValue(ci->getCalledOperand());
ops.insert(ops.begin(), calledValue);
- op = b.create<CallOp>(loc, tys, ops);
+ op = builder.create<CallOp>(loc, tys, ops);
}
if (!ci->getType()->isVoidTy())
mapValue(inst, op->getResult(0));
ops.push_back(processConstant(lpi->getClause(i)));
Type ty = convertType(lpi->getType());
- Value res = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
+ Value res = builder.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
mapValue(inst, res);
return success();
}
Operation *op;
if (llvm::Function *callee = ii->getCalledFunction()) {
- op = b.create<InvokeOp>(
- loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops,
- lookupBlock(ii->getNormalDest()), normalArgs,
+ op = builder.create<InvokeOp>(
+ loc, tys, SymbolRefAttr::get(builder.getContext(), callee->getName()),
+ ops, lookupBlock(ii->getNormalDest()), normalArgs,
lookupBlock(ii->getUnwindDest()), unwindArgs);
} else {
ops.insert(ops.begin(), processValue(ii->getCalledOperand()));
- op = b.create<InvokeOp>(loc, tys, ops, lookupBlock(ii->getNormalDest()),
- normalArgs, lookupBlock(ii->getUnwindDest()),
- unwindArgs);
+ op = builder.create<InvokeOp>(
+ loc, tys, ops, lookupBlock(ii->getNormalDest()), normalArgs,
+ lookupBlock(ii->getUnwindDest()), unwindArgs);
}
if (!ii->getType()->isVoidTy())
}
Type type = convertType(inst->getType());
- Value res = b.create<GEPOp>(loc, type, sourceElementType, basePtr, indices);
+ Value res =
+ builder.create<GEPOp>(loc, type, sourceElementType, basePtr, indices);
mapValue(inst, res);
return success();
}
// If it directly has a name, we can use it.
if (pf->hasName())
- return SymbolRefAttr::get(b.getContext(), pf->getName());
+ return SymbolRefAttr::get(builder.getContext(), pf->getName());
// If it doesn't have a name, currently, only function pointers that are
// bitcast to i8* are parsed.
if (ce->getOpcode() == llvm::Instruction::BitCast &&
ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) {
if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
- return SymbolRefAttr::get(b.getContext(), func->getName());
+ return SymbolRefAttr::get(builder.getContext(), func->getName());
}
}
return FlatSymbolRefAttr();
addNamedUnitAttr(LLVMDialect::getReadnoneAttrName());
}
-LogicalResult Importer::processFunction(llvm::Function *f) {
+LogicalResult Importer::processFunction(llvm::Function *func) {
blockMapping.clear();
valueMapping.clear();
auto functionType =
- convertType(f->getFunctionType()).dyn_cast<LLVMFunctionType>();
- if (f->isIntrinsic() && isConvertibleIntrinsic(f->getIntrinsicID()))
+ convertType(func->getFunctionType()).dyn_cast<LLVMFunctionType>();
+ if (func->isIntrinsic() && isConvertibleIntrinsic(func->getIntrinsicID()))
return success();
- bool dsoLocal = f->hasLocalLinkage();
- CConv cconv = convertCConvFromLLVM(f->getCallingConv());
+ bool dsoLocal = func->hasLocalLinkage();
+ CConv cconv = convertCConvFromLLVM(func->getCallingConv());
- b.setInsertionPoint(module.getBody(), getFuncInsertPt());
- LLVMFuncOp fop = b.create<LLVMFuncOp>(
- UnknownLoc::get(context), f->getName(), functionType,
- convertLinkageFromLLVM(f->getLinkage()), dsoLocal, cconv);
+ builder.setInsertionPoint(module.getBody(), getFuncInsertPt());
+ LLVMFuncOp funcOp = builder.create<LLVMFuncOp>(
+ UnknownLoc::get(context), func->getName(), functionType,
+ convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
- for (const auto &arg : llvm::enumerate(functionType.getParams())) {
+ for (const auto &it : llvm::enumerate(functionType.getParams())) {
llvm::SmallVector<NamedAttribute, 1> argAttrs;
- if (auto *type = f->getParamByValType(arg.index())) {
- auto mlirType = convertType(type);
+ if (auto *type = func->getParamByValType(it.index())) {
+ Type mlirType = convertType(type);
argAttrs.push_back(
- NamedAttribute(b.getStringAttr(LLVMDialect::getByValAttrName()),
+ NamedAttribute(builder.getStringAttr(LLVMDialect::getByValAttrName()),
TypeAttr::get(mlirType)));
}
- if (auto *type = f->getParamByRefType(arg.index())) {
- auto mlirType = convertType(type);
+ if (auto *type = func->getParamByRefType(it.index())) {
+ Type mlirType = convertType(type);
argAttrs.push_back(
- NamedAttribute(b.getStringAttr(LLVMDialect::getByRefAttrName()),
+ NamedAttribute(builder.getStringAttr(LLVMDialect::getByRefAttrName()),
TypeAttr::get(mlirType)));
}
- if (auto *type = f->getParamStructRetType(arg.index())) {
- auto mlirType = convertType(type);
- argAttrs.push_back(
- NamedAttribute(b.getStringAttr(LLVMDialect::getStructRetAttrName()),
- TypeAttr::get(mlirType)));
+ if (auto *type = func->getParamStructRetType(it.index())) {
+ Type mlirType = convertType(type);
+ argAttrs.push_back(NamedAttribute(
+ builder.getStringAttr(LLVMDialect::getStructRetAttrName()),
+ TypeAttr::get(mlirType)));
}
- if (auto *type = f->getParamInAllocaType(arg.index())) {
- auto mlirType = convertType(type);
- argAttrs.push_back(
- NamedAttribute(b.getStringAttr(LLVMDialect::getInAllocaAttrName()),
- TypeAttr::get(mlirType)));
+ if (auto *type = func->getParamInAllocaType(it.index())) {
+ Type mlirType = convertType(type);
+ argAttrs.push_back(NamedAttribute(
+ builder.getStringAttr(LLVMDialect::getInAllocaAttrName()),
+ TypeAttr::get(mlirType)));
}
- fop.setArgAttrs(arg.index(), argAttrs);
+ funcOp.setArgAttrs(it.index(), argAttrs);
}
- if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f))
- fop.setPersonalityAttr(personality);
- else if (f->hasPersonalityFn())
+ if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
+ funcOp.setPersonalityAttr(personality);
+ else if (func->hasPersonalityFn())
emitWarning(UnknownLoc::get(context),
"could not deduce personality, skipping it");
- if (f->hasGC())
- fop.setGarbageCollector(StringRef(f->getGC()));
+ if (func->hasGC())
+ funcOp.setGarbageCollector(StringRef(func->getGC()));
// Handle Function attributes.
- processFunctionAttributes(f, fop);
+ processFunctionAttributes(func, funcOp);
- if (f->isDeclaration())
+ if (func->isDeclaration())
return success();
// Eagerly create all blocks.
- for (llvm::BasicBlock &bb : *f) {
- Block *block = b.createBlock(&fop.getBody(), fop.getBody().end());
+ for (llvm::BasicBlock &bb : *func) {
+ Block *block =
+ builder.createBlock(&funcOp.getBody(), funcOp.getBody().end());
mapBlock(&bb, block);
}
- currentEntryBlock = &fop.getFunctionBody().getBlocks().front();
+ currentEntryBlock = &funcOp.getFunctionBody().getBlocks().front();
// Add function arguments to the entry block.
- for (const auto &it : llvm::enumerate(f->args())) {
- BlockArgument blockArg = fop.getFunctionBody().addArgument(
- functionType.getParamType(it.index()), fop.getLoc());
+ for (const auto &it : llvm::enumerate(func->args())) {
+ BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
+ functionType.getParamType(it.index()), funcOp.getLoc());
mapValue(&it.value(), blockArg);
}
// Process the blocks in topological order. The ordered traversal ensures
// operands defined in a dominating block have a valid mapping to an MLIR
// value once a block is translated.
- SetVector<llvm::BasicBlock *> blocks = getTopologicallySortedBlocks(f);
+ SetVector<llvm::BasicBlock *> blocks = getTopologicallySortedBlocks(func);
for (llvm::BasicBlock *bb : blocks) {
if (failed(processBasicBlock(bb, lookupBlock(bb))))
return failure();
}
LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) {
- b.setInsertionPointToStart(block);
+ builder.setInsertionPointToStart(block);
for (llvm::Instruction &inst : *bb) {
if (failed(processInstruction(&inst)))
return failure();