forked from OSchip/llvm-project
[mlir] Add support for LLVM's dso_local attr
This patch brings support for setting runtime preemption specifiers of LLVM's GlobalValues. In LLVM semantics, if the `dso_local` attribute is not explicitly requested, then it is inferred based on linkage and visibility. We model this same behavior with a UnitAttribute: if it is present, then we explicitly request the GlobalValue to marked as `dso_local`, otherwise we rely on the GlobalValue itself to make this decision. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D104983
This commit is contained in:
parent
355216380b
commit
8ca04b0513
|
@ -907,6 +907,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
|
|||
UnitAttr:$constant,
|
||||
StrAttr:$sym_name,
|
||||
Linkage:$linkage,
|
||||
UnitAttr:$dso_local,
|
||||
OptionalAttr<AnyAttr>:$value,
|
||||
OptionalAttr<I64Attr>:$alignment,
|
||||
DefaultValuedAttr<Confined<I32Attr, [IntNonNegative]>, "0">:$addr_space,
|
||||
|
@ -1017,6 +1018,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
|
|||
"StringRef":$name, "Attribute":$value,
|
||||
CArg<"uint64_t", "0">:$alignment,
|
||||
CArg<"unsigned", "0">:$addrSpace,
|
||||
CArg<"bool", "false">:$dsoLocal,
|
||||
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
|
||||
];
|
||||
|
||||
|
@ -1081,6 +1083,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func",
|
|||
}];
|
||||
|
||||
let arguments = (ins DefaultValuedAttr<Linkage, "Linkage::External">:$linkage,
|
||||
UnitAttr:$dso_local,
|
||||
OptionalAttr<FlatSymbolRefAttr>:$personality,
|
||||
OptionalAttr<ArrayAttr>:$passthrough);
|
||||
|
||||
|
@ -1091,6 +1094,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func",
|
|||
let builders = [
|
||||
OpBuilder<(ins "StringRef":$name, "Type":$type,
|
||||
CArg<"Linkage", "Linkage::External">:$linkage,
|
||||
CArg<"bool", "false">:$dsoLocal,
|
||||
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
|
||||
CArg<"ArrayRef<DictionaryAttr>", "{}">:$argAttrs)>
|
||||
];
|
||||
|
|
|
@ -70,7 +70,7 @@ GPUFuncOpLowering::matchAndRewrite(gpu::GPUFuncOp gpuFuncOp,
|
|||
attributes.emplace_back(kernelAttributeName, rewriter.getUnitAttr());
|
||||
auto llvmFuncOp = rewriter.create<LLVM::LLVMFuncOp>(
|
||||
gpuFuncOp.getLoc(), gpuFuncOp.getName(), funcType,
|
||||
LLVM::Linkage::External, attributes);
|
||||
LLVM::Linkage::External, /*dsoLocal*/ false, attributes);
|
||||
|
||||
{
|
||||
// Insert operations that correspond to converted workgroup and private
|
||||
|
|
|
@ -1266,7 +1266,7 @@ static void wrapForExternalCallers(OpBuilder &rewriter, Location loc,
|
|||
typeConverter.convertFunctionTypeCWrapper(type);
|
||||
auto wrapperFuncOp = rewriter.create<LLVM::LLVMFuncOp>(
|
||||
loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(),
|
||||
wrapperFuncType, LLVM::Linkage::External, attributes);
|
||||
wrapperFuncType, LLVM::Linkage::External, /*dsoLocal*/ false, attributes);
|
||||
|
||||
OpBuilder::InsertionGuard guard(rewriter);
|
||||
rewriter.setInsertionPointToStart(wrapperFuncOp.addEntryBlock());
|
||||
|
@ -1330,7 +1330,7 @@ static void wrapExternalFunction(OpBuilder &builder, Location loc,
|
|||
// Create the auxiliary function.
|
||||
auto wrapperFunc = builder.create<LLVM::LLVMFuncOp>(
|
||||
loc, llvm::formatv("_mlir_ciface_{0}", funcOp.getName()).str(),
|
||||
wrapperType, LLVM::Linkage::External, attributes);
|
||||
wrapperType, LLVM::Linkage::External, /*dsoLocal*/ false, attributes);
|
||||
|
||||
builder.setInsertionPointToStart(newFuncOp.addEntryBlock());
|
||||
|
||||
|
@ -1441,7 +1441,7 @@ protected:
|
|||
// functions have linkage.
|
||||
auto newFuncOp = rewriter.create<LLVM::LLVMFuncOp>(
|
||||
funcOp.getLoc(), funcOp.getName(), llvmType, LLVM::Linkage::External,
|
||||
attributes);
|
||||
/*dsoLocal*/ false, attributes);
|
||||
rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
|
||||
newFuncOp.end());
|
||||
if (failed(rewriter.convertRegionTypes(&newFuncOp.getBody(), *typeConverter,
|
||||
|
|
|
@ -1267,7 +1267,7 @@ static StringRef getUnnamedAddrAttrName() { return "unnamed_addr"; }
|
|||
void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
|
||||
bool isConstant, Linkage linkage, StringRef name,
|
||||
Attribute value, uint64_t alignment, unsigned addrSpace,
|
||||
ArrayRef<NamedAttribute> attrs) {
|
||||
bool dsoLocal, ArrayRef<NamedAttribute> attrs) {
|
||||
result.addAttribute(SymbolTable::getSymbolAttrName(),
|
||||
builder.getStringAttr(name));
|
||||
result.addAttribute("type", TypeAttr::get(type));
|
||||
|
@ -1275,6 +1275,8 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
|
|||
result.addAttribute("constant", builder.getUnitAttr());
|
||||
if (value)
|
||||
result.addAttribute("value", value);
|
||||
if (dsoLocal)
|
||||
result.addAttribute("dso_local", builder.getUnitAttr());
|
||||
|
||||
// Only add an alignment attribute if the "alignment" input
|
||||
// is different from 0. The value must also be a power of two, but
|
||||
|
@ -1756,7 +1758,7 @@ Block *LLVMFuncOp::addEntryBlock() {
|
|||
|
||||
void LLVMFuncOp::build(OpBuilder &builder, OperationState &result,
|
||||
StringRef name, Type type, LLVM::Linkage linkage,
|
||||
ArrayRef<NamedAttribute> attrs,
|
||||
bool dsoLocal, ArrayRef<NamedAttribute> attrs,
|
||||
ArrayRef<DictionaryAttr> argAttrs) {
|
||||
result.addRegion();
|
||||
result.addAttribute(SymbolTable::getSymbolAttrName(),
|
||||
|
@ -1765,6 +1767,8 @@ void LLVMFuncOp::build(OpBuilder &builder, OperationState &result,
|
|||
result.addAttribute(getLinkageAttrName(),
|
||||
builder.getI64IntegerAttr(static_cast<int64_t>(linkage)));
|
||||
result.attributes.append(attrs.begin(), attrs.end());
|
||||
if (dsoLocal)
|
||||
result.addAttribute("dso_local", builder.getUnitAttr());
|
||||
if (argAttrs.empty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -425,6 +425,14 @@ static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage,
|
|||
linkage == llvm::GlobalVariable::ExternalWeakLinkage;
|
||||
}
|
||||
|
||||
/// Sets the runtime preemption specifier of `gv` to dso_local if
|
||||
/// `dsoLocalRequested` is true, otherwise it is left unchanged.
|
||||
static void addRuntimePreemptionSpecifier(bool dsoLocalRequested,
|
||||
llvm::GlobalValue *gv) {
|
||||
if (dsoLocalRequested)
|
||||
gv->setDSOLocal(true);
|
||||
}
|
||||
|
||||
/// Create named global variables that correspond to llvm.mlir.global
|
||||
/// definitions.
|
||||
LogicalResult ModuleTranslation::convertGlobals() {
|
||||
|
@ -458,6 +466,8 @@ LogicalResult ModuleTranslation::convertGlobals() {
|
|||
if (op.section().hasValue())
|
||||
var->setSection(*op.section());
|
||||
|
||||
addRuntimePreemptionSpecifier(op.dso_local(), var);
|
||||
|
||||
Optional<uint64_t> alignment = op.alignment();
|
||||
if (alignment.hasValue())
|
||||
var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
|
||||
|
@ -687,6 +697,7 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
|
|||
llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
|
||||
llvmFunc->setLinkage(convertLinkageToLLVM(function.linkage()));
|
||||
mapFunction(function.getName(), llvmFunc);
|
||||
addRuntimePreemptionSpecifier(function.dso_local(), llvmFunc);
|
||||
|
||||
// Forward the pass-through attributes to LLVM.
|
||||
if (failed(forwardPassthroughAttributes(function.getLoc(),
|
||||
|
|
|
@ -79,6 +79,13 @@ llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i6
|
|||
// CHECK: @unnamed_addr = private unnamed_addr constant i64 42
|
||||
llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64
|
||||
|
||||
//
|
||||
// dso_local attribute.
|
||||
//
|
||||
|
||||
llvm.mlir.global @has_dso_local(42 : i64) {dso_local} : i64
|
||||
// CHECK: @has_dso_local = dso_local global i64 42
|
||||
|
||||
//
|
||||
// Section attribute.
|
||||
//
|
||||
|
@ -428,6 +435,15 @@ llvm.func internal @func_internal() {
|
|||
llvm.return
|
||||
}
|
||||
|
||||
//
|
||||
// dso_local attribute.
|
||||
//
|
||||
|
||||
// CHECK: define dso_local void @dso_local_func
|
||||
llvm.func @dso_local_func() attributes {dso_local} {
|
||||
llvm.return
|
||||
}
|
||||
|
||||
//
|
||||
// MemRef type conversion, allocation and communication with functions.
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue