Skip to content

Commit 29a0000

Browse files
bcardosolopesgysitxlauko
authored
[MLIR][LLVMIR] Add module flags support (#130679)
Import and translation support. Note that existing support (prior to this PR) already covers enough in translation specifically to emit "Debug Info Version". Also, the debug info version metadata is being emitted even though the imported IR has no information and is showing up in some tests (will fix that in another PR). --------- Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com> Co-authored-by: Henrich Lauko <xlauko@mail.muni.cz>
1 parent b785293 commit 29a0000

File tree

14 files changed

+229
-0
lines changed

14 files changed

+229
-0
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,4 +1291,29 @@ def LLVM_DereferenceableAttr : LLVM_Attr<"Dereferenceable", "dereferenceable"> {
12911291
let assemblyFormat = "`<` struct(params) `>`";
12921292
}
12931293

1294+
//===----------------------------------------------------------------------===//
1295+
// ModuleFlagAttr
1296+
//===----------------------------------------------------------------------===//
1297+
1298+
def ModuleFlagAttr
1299+
: LLVM_Attr<"ModuleFlag", "mlir.module_flag"> {
1300+
let summary = "LLVM module flag metadata";
1301+
let description = [{
1302+
Represents a single entry of llvm.module.flags metadata
1303+
(llvm::Module::ModuleFlagEntry in LLVM). The first element is a behavior
1304+
flag described by `ModFlagBehaviorAttr`, the second is a string ID
1305+
and third is the value of the flag (currently only integer constants
1306+
are supported).
1307+
1308+
Example:
1309+
```mlir
1310+
#llvm.mlir.module_flag<error, "wchar_size", 4>
1311+
```
1312+
}];
1313+
let parameters = (ins "ModFlagBehavior":$behavior,
1314+
"StringAttr":$key,
1315+
"uint32_t":$value);
1316+
let assemblyFormat = "`<` $behavior `,` $key `,` $value `>`";
1317+
}
1318+
12941319
#endif // LLVMIR_ATTRDEFS

mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def LLVM_Dialect : Dialect {
3333
static StringRef getAliasScopesAttrName() { return "alias_scopes"; }
3434
static StringRef getAccessGroupsAttrName() { return "access_groups"; }
3535
static StringRef getIdentAttrName() { return "llvm.ident"; }
36+
static StringRef getModuleFlags() { return "llvm.module.flags"; }
3637
static StringRef getCommandlineAttrName() { return "llvm.commandline"; }
3738

3839
/// Names of llvm parameter attributes.

mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,4 +818,37 @@ def FPExceptionBehaviorAttr : LLVM_EnumAttr<
818818
let cppNamespace = "::mlir::LLVM";
819819
}
820820

821+
//===----------------------------------------------------------------------===//
822+
// Module Flag Behavior
823+
//===----------------------------------------------------------------------===//
824+
825+
// These values must match llvm::Module::ModFlagBehavior ones.
826+
// See llvm/include/llvm/IR/Module.h.
827+
def ModFlagBehaviorError
828+
: LLVM_EnumAttrCase<"Error", "error", "Error", 1>;
829+
def ModFlagBehaviorWarning
830+
: LLVM_EnumAttrCase<"Warning", "warning", "Warning", 2>;
831+
def ModFlagBehaviorRequire
832+
: LLVM_EnumAttrCase<"Require", "require", "Require", 3>;
833+
def ModFlagBehaviorOverride
834+
: LLVM_EnumAttrCase<"Override", "override", "Override", 4>;
835+
def ModFlagBehaviorAppend
836+
: LLVM_EnumAttrCase<"Append", "append", "Append", 5>;
837+
def ModFlagBehaviorAppendUnique
838+
: LLVM_EnumAttrCase<"AppendUnique", "append_unique", "AppendUnique", 6>;
839+
def ModFlagBehaviorMax
840+
: LLVM_EnumAttrCase<"Max", "max", "Max", 7>;
841+
def ModFlagBehaviorMin
842+
: LLVM_EnumAttrCase<"Min", "min", "Min", 8>;
843+
844+
def ModFlagBehaviorAttr : LLVM_EnumAttr<
845+
"ModFlagBehavior",
846+
"::llvm::Module::ModFlagBehavior",
847+
"LLVM Module Flag Behavior",
848+
[ModFlagBehaviorError, ModFlagBehaviorWarning, ModFlagBehaviorRequire,
849+
ModFlagBehaviorOverride, ModFlagBehaviorAppend,
850+
ModFlagBehaviorAppendUnique, ModFlagBehaviorMax, ModFlagBehaviorMin]> {
851+
let cppNamespace = "::mlir::LLVM";
852+
}
853+
821854
#endif // LLVMIR_ENUMS

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,4 +2183,36 @@ def LLVM_LinkerOptionsOp
21832183
let hasVerifier = 1;
21842184
}
21852185

2186+
//===--------------------------------------------------------------------===//
2187+
// ModuleFlagsOp
2188+
//===--------------------------------------------------------------------===//
2189+
2190+
def LLVM_ModuleFlagsOp
2191+
: LLVM_Op<"module_flags"> {
2192+
let summary = "Information about module properties";
2193+
let description = [{
2194+
Represents the equivalent in MLIR for LLVM's `llvm.module.flags` metadata,
2195+
which requires a list of metadata triplets. Each triplet entry is described
2196+
by a `ModuleFlagAttr`.
2197+
2198+
Example:
2199+
```mlir
2200+
llvm.module.flags [
2201+
#llvm.mlir.module_flag<error, "wchar_size", 4>,
2202+
#llvm.mlir.module_flag<max, "PIC Level", 2>
2203+
]
2204+
```
2205+
}];
2206+
let arguments = (ins ArrayAttr:$flags);
2207+
let assemblyFormat = [{
2208+
$flags attr-dict
2209+
}];
2210+
2211+
let llvmBuilder = [{
2212+
convertModuleFlagsOp($flags, builder, moduleTranslation);
2213+
}];
2214+
2215+
let hasVerifier = 1;
2216+
}
2217+
21862218
#endif // LLVMIR_OPS

mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ class ModuleImport {
218218
/// LLVM dialect operation.
219219
LogicalResult convertLinkerOptionsMetadata();
220220

221+
/// Converts !llvm.module.flags metadata.
222+
LogicalResult convertModuleFlagsMetadata();
223+
221224
/// Converts !llvm.ident metadata to the llvm.ident LLVM ModuleOp attribute.
222225
LogicalResult convertIdentMetadata();
223226

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,6 +3712,20 @@ LogicalResult LinkerOptionsOp::verify() {
37123712
return success();
37133713
}
37143714

3715+
//===----------------------------------------------------------------------===//
3716+
// ModuleFlagsOp
3717+
//===----------------------------------------------------------------------===//
3718+
3719+
LogicalResult ModuleFlagsOp::verify() {
3720+
if (Operation *parentOp = (*this)->getParentOp();
3721+
parentOp && !satisfiesLLVMModule(parentOp))
3722+
return emitOpError("must appear at the module level");
3723+
for (Attribute flag : getFlags())
3724+
if (!isa<ModuleFlagAttr>(flag))
3725+
return emitOpError("expected a module flag attribute");
3726+
return success();
3727+
}
3728+
37153729
//===----------------------------------------------------------------------===//
37163730
// InlineAsmOp
37173731
//===----------------------------------------------------------------------===//

mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,15 @@ static void convertLinkerOptionsOp(ArrayAttr options,
270270
linkerMDNode->addOperand(listMDNode);
271271
}
272272

273+
static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
274+
LLVM::ModuleTranslation &moduleTranslation) {
275+
llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
276+
for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>())
277+
llvmModule->addModuleFlag(
278+
convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
279+
flagAttr.getKey().getValue(), flagAttr.getValue());
280+
}
281+
273282
static LogicalResult
274283
convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
275284
LLVM::ModuleTranslation &moduleTranslation) {

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,33 @@ void ModuleImport::addDebugIntrinsic(llvm::CallInst *intrinsic) {
517517
debugIntrinsics.insert(intrinsic);
518518
}
519519

520+
LogicalResult ModuleImport::convertModuleFlagsMetadata() {
521+
SmallVector<llvm::Module::ModuleFlagEntry> llvmModuleFlags;
522+
llvmModule->getModuleFlagsMetadata(llvmModuleFlags);
523+
524+
SmallVector<Attribute> moduleFlags;
525+
for (const auto [behavior, key, val] : llvmModuleFlags) {
526+
// Currently only supports most common: int constant values.
527+
auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val);
528+
if (!constInt) {
529+
emitWarning(mlirModule.getLoc())
530+
<< "unsupported module flag value: " << diagMD(val, llvmModule.get())
531+
<< ", only constant integer currently supported";
532+
continue;
533+
}
534+
535+
moduleFlags.push_back(builder.getAttr<ModuleFlagAttr>(
536+
convertModFlagBehaviorFromLLVM(behavior),
537+
builder.getStringAttr(key->getString()), constInt->getZExtValue()));
538+
}
539+
540+
if (!moduleFlags.empty())
541+
builder.create<LLVM::ModuleFlagsOp>(mlirModule.getLoc(),
542+
builder.getArrayAttr(moduleFlags));
543+
544+
return success();
545+
}
546+
520547
LogicalResult ModuleImport::convertLinkerOptionsMetadata() {
521548
for (const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
522549
if (named.getName() != "llvm.linker.options")
@@ -596,6 +623,8 @@ LogicalResult ModuleImport::convertMetadata() {
596623
}
597624
if (failed(convertLinkerOptionsMetadata()))
598625
return failure();
626+
if (failed(convertModuleFlagsMetadata()))
627+
return failure();
599628
if (failed(convertIdentMetadata()))
600629
return failure();
601630
if (failed(convertCommandlineMetadata()))

mlir/test/Dialect/LLVMIR/invalid.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,3 +1764,10 @@ llvm.mlir.alias external @y5 : i32 {
17641764
llvm.return %0 : !llvm.ptr<4>
17651765
}
17661766

1767+
// -----
1768+
1769+
module {
1770+
// expected-error@+2 {{expected integer value}}
1771+
// expected-error@+1 {{failed to parse ModuleFlagAttr parameter 'value' which is to be a `uint32_t`}}
1772+
llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", "yolo">]
1773+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: mlir-opt %s | mlir-opt | FileCheck %s
2+
3+
module {
4+
llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>,
5+
#llvm.mlir.module_flag<min, "PIC Level", 2>,
6+
#llvm.mlir.module_flag<max, "PIE Level", 2>,
7+
#llvm.mlir.module_flag<max, "uwtable", 2>,
8+
#llvm.mlir.module_flag<max, "frame-pointer", 1>]
9+
}
10+
11+
// CHECK: llvm.module_flags [
12+
// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>,
13+
// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>,
14+
// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>,
15+
// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>,
16+
// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>]

0 commit comments

Comments
 (0)