From d328d410613963359c4044292cfca99388d01023 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 12:08:33 +0900 Subject: [PATCH 01/10] Revert "Add a pass to collect dropped var stats for MIR (#120780)" This reverts commit 3bf91ad2a9c75dd045961e45fdd830fd7b7a5455. (llvmorg-20-init-16123-g3bf91ad2a9c7) `llvm/CodeGen` should not depend on `llvm/Passes`. --- .../llvm/CodeGen/DroppedVariableStatsMIR.h | 70 -- .../llvm/CodeGen/MachineFunctionPass.h | 2 - llvm/lib/CodeGen/CMakeLists.txt | 1 - llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp | 77 -- llvm/lib/CodeGen/MachineFunctionPass.cpp | 15 +- llvm/unittests/CodeGen/CMakeLists.txt | 1 - .../CodeGen/DroppedVariableStatsMIRTest.cpp | 1080 ----------------- 7 files changed, 1 insertion(+), 1245 deletions(-) delete mode 100644 llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h delete mode 100644 llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp delete mode 100644 llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp diff --git a/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h b/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h deleted file mode 100644 index 462bbb8b404bcf..00000000000000 --- a/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h +++ /dev/null @@ -1,70 +0,0 @@ -///===- DroppedVariableStatsMIR.h - Opt Diagnostics -*- C++ -*-------------===// -/// -/// Part of the LLVM Project, under the Apache License v2.0 with LLVM -/// Exceptions. See https://llvm.org/LICENSE.txt for license information. -/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -/// -///===---------------------------------------------------------------------===// -/// \file -/// Dropped Variable Statistics for Debug Information. Reports any number -/// of DBG_VALUEs that get dropped due to an optimization pass. -/// -///===---------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H -#define LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H - -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Passes/DroppedVariableStats.h" - -namespace llvm { - -/// A class to collect and print dropped debug information due to MIR -/// optimization passes. After every MIR pass is run, it will print how many -/// #DBG_VALUEs were dropped due to that pass. -class DroppedVariableStatsMIR : public DroppedVariableStats { -public: - DroppedVariableStatsMIR() : llvm::DroppedVariableStats(false) {} - - void runBeforePass(StringRef PassID, MachineFunction *MF) { - if (PassID == "Debug Variable Analysis") - return; - setup(); - return runOnMachineFunction(MF, true); - } - - void runAfterPass(StringRef PassID, MachineFunction *MF) { - if (PassID == "Debug Variable Analysis") - return; - runOnMachineFunction(MF, false); - calculateDroppedVarStatsOnMachineFunction(MF, PassID, MF->getName().str()); - cleanup(); - } - -private: - const MachineFunction *MFunc; - /// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or - /// after a pass has run to facilitate dropped variable calculation for an - /// llvm::MachineFunction. - void runOnMachineFunction(const MachineFunction *MF, bool Before); - /// Iterate over all Instructions in a MachineFunction and report any dropped - /// debug information. - void calculateDroppedVarStatsOnMachineFunction(const MachineFunction *MF, - StringRef PassID, - StringRef FuncOrModName); - /// Override base class method to run on an llvm::MachineFunction - /// specifically. - virtual void - visitEveryInstruction(unsigned &DroppedCount, - DenseMap &InlinedAtsMap, - VarID Var) override; - /// Override base class method to run on DBG_VALUEs specifically. - virtual void visitEveryDebugRecord( - DenseSet &VarIDSet, - DenseMap> &InlinedAtsMap, - StringRef FuncName, bool Before) override; -}; - -} // namespace llvm - -#endif diff --git a/llvm/include/llvm/CodeGen/MachineFunctionPass.h b/llvm/include/llvm/CodeGen/MachineFunctionPass.h index 8d7e4192003d22..caaf22c2139e31 100644 --- a/llvm/include/llvm/CodeGen/MachineFunctionPass.h +++ b/llvm/include/llvm/CodeGen/MachineFunctionPass.h @@ -18,7 +18,6 @@ #ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H #define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H -#include "llvm/CodeGen/DroppedVariableStatsMIR.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Pass.h" @@ -68,7 +67,6 @@ class MachineFunctionPass : public FunctionPass { MachineFunctionProperties RequiredProperties; MachineFunctionProperties SetProperties; MachineFunctionProperties ClearedProperties; - DroppedVariableStatsMIR DroppedVarStatsMF; /// createPrinterPass - Get a machine function printer pass. Pass *createPrinterPass(raw_ostream &O, diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index b8cefcc1acd22f..145fd2fac8b564 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -50,7 +50,6 @@ add_llvm_component_library(LLVMCodeGen DeadMachineInstructionElim.cpp DetectDeadLanes.cpp DFAPacketizer.cpp - DroppedVariableStatsMIR.cpp DwarfEHPrepare.cpp EarlyIfConversion.cpp EdgeBundles.cpp diff --git a/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp b/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp deleted file mode 100644 index 4379db8b166791..00000000000000 --- a/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp +++ /dev/null @@ -1,77 +0,0 @@ -///===- DroppedVariableStatsMIR.cpp ---------------------------------------===// -/// -/// Part of the LLVM Project, under the Apache License v2.0 with LLVM -/// Exceptions. See https://llvm.org/LICENSE.txt for license information. -/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -/// -///===---------------------------------------------------------------------===// -/// \file -/// Dropped Variable Statistics for Debug Information. Reports any number -/// of DBG_VALUEs that get dropped due to an optimization pass. -/// -///===---------------------------------------------------------------------===// - -#include "llvm/CodeGen/DroppedVariableStatsMIR.h" - -using namespace llvm; - -void DroppedVariableStatsMIR::runOnMachineFunction(const MachineFunction *MF, - bool Before) { - auto &DebugVariables = DebugVariablesStack.back()[&MF->getFunction()]; - auto FuncName = MF->getName(); - MFunc = MF; - run(DebugVariables, FuncName, Before); -} - -void DroppedVariableStatsMIR::calculateDroppedVarStatsOnMachineFunction( - const MachineFunction *MF, StringRef PassID, StringRef FuncOrModName) { - MFunc = MF; - StringRef FuncName = MF->getName(); - const Function *Func = &MF->getFunction(); - DebugVariables &DbgVariables = DebugVariablesStack.back()[Func]; - calculateDroppedStatsAndPrint(DbgVariables, FuncName, PassID, FuncOrModName, - "MachineFunction", Func); -} - -void DroppedVariableStatsMIR::visitEveryInstruction( - unsigned &DroppedCount, DenseMap &InlinedAtsMap, - VarID Var) { - unsigned PrevDroppedCount = DroppedCount; - const DIScope *DbgValScope = std::get<0>(Var); - for (const auto &MBB : *MFunc) { - for (const auto &MI : MBB) { - if (!MI.isDebugInstr()) { - auto *DbgLoc = MI.getDebugLoc().get(); - if (!DbgLoc) - continue; - - auto *Scope = DbgLoc->getScope(); - if (updateDroppedCount(DbgLoc, Scope, DbgValScope, InlinedAtsMap, Var, - DroppedCount)) - break; - } - } - if (PrevDroppedCount != DroppedCount) { - PrevDroppedCount = DroppedCount; - break; - } - } -} - -void DroppedVariableStatsMIR::visitEveryDebugRecord( - DenseSet &VarIDSet, - DenseMap> &InlinedAtsMap, - StringRef FuncName, bool Before) { - for (const auto &MBB : *MFunc) { - for (const auto &MI : MBB) { - if (MI.isDebugValueLike()) { - auto *DbgVar = MI.getDebugVariable(); - if (!DbgVar) - continue; - auto DbgLoc = MI.getDebugLoc(); - populateVarIDSetAndInlinedMap(DbgVar, DbgLoc, VarIDSet, InlinedAtsMap, - FuncName, Before); - } - } - } -} \ No newline at end of file diff --git a/llvm/lib/CodeGen/MachineFunctionPass.cpp b/llvm/lib/CodeGen/MachineFunctionPass.cpp index e803811643f874..62ac3e32d24d9d 100644 --- a/llvm/lib/CodeGen/MachineFunctionPass.cpp +++ b/llvm/lib/CodeGen/MachineFunctionPass.cpp @@ -32,11 +32,6 @@ using namespace llvm; using namespace ore; -static cl::opt DroppedVarStatsMIR( - "dropped-variable-stats-mir", cl::Hidden, - cl::desc("Dump dropped debug variables stats for MIR passes"), - cl::init(false)); - Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O, const std::string &Banner) const { return createMachineFunctionPrinterPass(O, Banner); @@ -96,15 +91,7 @@ bool MachineFunctionPass::runOnFunction(Function &F) { MFProps.reset(ClearedProperties); - bool RV; - if (DroppedVarStatsMIR) { - auto PassName = getPassName(); - DroppedVarStatsMF.runBeforePass(PassName, &MF); - RV = runOnMachineFunction(MF); - DroppedVarStatsMF.runAfterPass(PassName, &MF); - } else { - RV = runOnMachineFunction(MF); - } + bool RV = runOnMachineFunction(MF); if (ShouldEmitSizeRemarks) { // We wanted size remarks. Check if there was a change to the number of diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt index 4f580e7539f4d9..963cdcc0275e16 100644 --- a/llvm/unittests/CodeGen/CMakeLists.txt +++ b/llvm/unittests/CodeGen/CMakeLists.txt @@ -27,7 +27,6 @@ add_llvm_unittest(CodeGenTests CCStateTest.cpp DIEHashTest.cpp DIETest.cpp - DroppedVariableStatsMIRTest.cpp DwarfStringPoolEntryRefTest.cpp InstrRefLDVTest.cpp LowLevelTypeTest.cpp diff --git a/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp b/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp deleted file mode 100644 index b3d6da575f3bae..00000000000000 --- a/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp +++ /dev/null @@ -1,1080 +0,0 @@ -//===- unittests/CodeGen/DroppedVariableStatsMIRTest.cpp ------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/DroppedVariableStatsMIR.h" -#include "llvm/AsmParser/Parser.h" -#include "llvm/CodeGen/MIRParser/MIRParser.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Pass.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetMachine.h" -#include "gtest/gtest.h" -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace llvm; - -namespace { - -std::unique_ptr -createTargetMachine(std::string TT, StringRef CPU, StringRef FS) { - std::string Error; - const Target *T = TargetRegistry::lookupTarget(TT, Error); - if (!T) - return nullptr; - TargetOptions Options; - return std::unique_ptr( - static_cast(T->createTargetMachine( - TT, CPU, FS, Options, std::nullopt, std::nullopt))); -} - -std::unique_ptr parseMIR(const TargetMachine &TM, StringRef MIRCode, - MachineModuleInfo &MMI, LLVMContext *Context) { - SMDiagnostic Diagnostic; - std::unique_ptr M; - std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRCode); - auto MIR = createMIRParser(std::move(MBuffer), *Context); - if (!MIR) - return nullptr; - - std::unique_ptr Mod = MIR->parseIRModule(); - if (!Mod) - return nullptr; - - Mod->setDataLayout(TM.createDataLayout()); - - if (MIR->parseMachineFunctions(*Mod, MMI)) { - M.reset(); - return nullptr; - } - return Mod; -} -// This test ensures that if a DBG_VALUE and an instruction that exists in the -// same scope as that DBG_VALUE are both deleted as a result of an optimization -// pass, debug information is considered not dropped. -TEST(DroppedVariableStatsMIR, BothDeleted) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4) - !12 = !DILocation(line: 2, column: 11, scope: !4) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - for (auto &MI : MBB) { - auto *DbgLoc = MI.getDebugLoc().get(); - if (DbgLoc) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), false); -} - -// This test ensures that if a DBG_VALUE is dropped after an optimization pass, -// but an instruction that shares the same scope as the DBG_VALUE still exists, -// debug information is conisdered dropped. -TEST(DroppedVariableStatsMIR, DbgValLost) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4) - !12 = !DILocation(line: 2, column: 11, scope: !4) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), true); -} - -// This test ensures that if a #dbg_value is dropped after an optimization pass, -// but an instruction that has an unrelated scope as the #dbg_value still -// exists, debug information is conisdered not dropped. -TEST(DroppedVariableStatsMIR, UnrelatedScopes) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4) - !12 = !DILocation(line: 2, column: 11, scope: !13) - !13 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), false); -} - -// This test ensures that if a #dbg_value is dropped after an optimization pass, -// but an instruction that has a scope which is a child of the #dbg_value scope -// still exists, debug information is conisdered dropped. -TEST(DroppedVariableStatsMIR, ChildScopes) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4) - !12 = !DILocation(line: 2, column: 11, scope: !13) - !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), true); -} - -// This test ensures that if a DBG_VALUE is dropped after an optimization pass, -// but an instruction that has a scope which is a child of the DBG_VALUE scope -// still exists, and the DBG_VALUE is inlined at another location, debug -// information is conisdered not dropped. -TEST(DroppedVariableStatsMIR, InlinedAt) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14) - !12 = !DILocation(line: 2, column: 11, scope: !13) - !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28) - !14 = !DILocation(line: 3, column: 2, scope: !4) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), false); -} - -// This test ensures that if a DBG_VALUE is dropped after an optimization pass, -// but an instruction that has a scope which is a child of the DBG_VALUE scope -// still exists, and the DBG_VALUE and the instruction are inlined at another -// location, debug information is conisdered dropped. -TEST(DroppedVariableStatsMIR, InlinedAtShared) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14) - !12 = !DILocation(line: 2, column: 11, scope: !13, inlinedAt: !14) - !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28) - !14 = !DILocation(line: 3, column: 2, scope: !4) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), true); -} - -// This test ensures that if a DBG_VALUE is dropped after an optimization pass, -// but an instruction that has a scope which is a child of the DBG_VALUE scope -// still exists, and the instruction is inlined at a location that is the -// DBG_VALUE's inlined at location, debug information is conisdered dropped. -TEST(DroppedVariableStatsMIR, InlinedAtChild) { - InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllTargetMCs(); - PassInstrumentationCallbacks PIC; - PassInstrumentation PI(&PIC); - - LLVMContext C; - - const char *MIR = - R"( ---- | - ; ModuleID = '/tmp/test.ll' - source_filename = "/tmp/test.ll" - target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" - - define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 { - entry: - #dbg_value(i32 %x, !10, !DIExpression(), !11) - %add = add nsw i32 %x, 1, !dbg !12 - ret i32 0 - } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2} - !llvm.ident = !{!3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") - !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/") - !2 = !{i32 2, !"Debug Info Version", i32 3} - !3 = !{!"clang"} - !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !5 = !DIFile(filename: "/tmp/code.cpp", directory: "") - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{!10} - !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8) - !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14) - !12 = !DILocation(line: 2, column: 11, scope: !13, inlinedAt: !15) - !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28) - !14 = !DILocation(line: 3, column: 2, scope: !4) - !15 = !DILocation(line: 4, column: 5, scope: !13, inlinedAt: !14) - -... ---- -name: _Z3fooi -alignment: 4 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: false -isSSA: true -noVRegs: false -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: _, preferred-register: '', flags: [ ] } - - { id: 1, class: _, preferred-register: '', flags: [ ] } - - { id: 2, class: _, preferred-register: '', flags: [ ] } - - { id: 3, class: _, preferred-register: '', flags: [ ] } -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: false - hasCalls: false - stackProtector: '' - functionContext: '' - maxCallFrameSize: 4294967295 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.1.entry: - liveins: $w0 - - %0:_(s32) = COPY $w0 - %1:_(s32) = G_CONSTANT i32 1 - %3:_(s32) = G_CONSTANT i32 0 - DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11 - %2:_(s32) = nsw G_ADD %0, %1, debug-location !12 - $w0 = COPY %3(s32) - RET_ReallyLR implicit $w0 - )"; - auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", ""); - if (!TM) - return; - MachineModuleInfo MMI(TM.get()); - std::unique_ptr M = parseMIR(*TM, MIR, MMI, &C); - ASSERT_TRUE(M); - - DroppedVariableStatsMIR Stats; - auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi")); - Stats.runBeforePass("Test", MF); - - // This loop simulates an IR pass that drops debug information. - for (auto &MBB : *MF) { - for (auto &MI : MBB) { - if (MI.isDebugValueLike()) { - MI.eraseFromParent(); - break; - } - } - break; - } - - Stats.runAfterPass("Test", MF); - ASSERT_EQ(Stats.getPassDroppedVariables(), true); -} - -} // end anonymous namespace \ No newline at end of file From 559f0809cc69f0ee55fa56fac1758f43863f2650 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot Date: Sat, 21 Dec 2024 03:43:14 +0000 Subject: [PATCH 02/10] [gn build] Port d328d4106139 --- llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn | 1 - llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn | 1 - 2 files changed, 2 deletions(-) diff --git a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn index 99abbc8ae57b88..ab72ac4ae9f4bb 100644 --- a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn @@ -50,7 +50,6 @@ static_library("CodeGen") { "DFAPacketizer.cpp", "DeadMachineInstructionElim.cpp", "DetectDeadLanes.cpp", - "DroppedVariableStatsMIR.cpp", "DwarfEHPrepare.cpp", "EHContGuardCatchret.cpp", "EarlyIfConversion.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn index 2fbc1271996093..a3f89a5648cb5c 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn @@ -26,7 +26,6 @@ unittest("CodeGenTests") { "CCStateTest.cpp", "DIEHashTest.cpp", "DIETest.cpp", - "DroppedVariableStatsMIRTest.cpp", "DwarfStringPoolEntryRefTest.cpp", "InstrRefLDVTest.cpp", "LexicalScopesTest.cpp", From 5cd427477218d8bdb659c6c53a7758f741c3990a Mon Sep 17 00:00:00 2001 From: Peter Hawkins Date: Fri, 20 Dec 2024 23:32:32 -0500 Subject: [PATCH 03/10] [mlir python] Port in-tree dialects to nanobind. (#119924) This is a companion to #118583, although it can be landed independently because since #117922 dialects do not have to use the same Python binding framework as the Python core code. This PR ports all of the in-tree dialect and pass extensions to nanobind, with the exception of those that remain for testing pybind11 support. This PR also: * removes CollectDiagnosticsToStringScope from NanobindAdaptors.h. This was overlooked in a previous PR and it is duplicated in Diagnostics.h. --------- Co-authored-by: Jacques Pienaar --- mlir/cmake/modules/AddMLIRPython.cmake | 12 +++ mlir/cmake/modules/MLIRDetectPythonEnv.cmake | 12 +++ .../python/StandaloneExtensionNanobind.cpp | 3 +- mlir/include/mlir/Bindings/Python/Nanobind.h | 37 ++++++++ .../mlir/Bindings/Python/NanobindAdaptors.h | 40 +-------- mlir/lib/Bindings/Python/AsyncPasses.cpp | 5 +- mlir/lib/Bindings/Python/DialectGPU.cpp | 44 +++++----- mlir/lib/Bindings/Python/DialectLLVM.cpp | 54 ++++++------ mlir/lib/Bindings/Python/DialectLinalg.cpp | 11 +-- mlir/lib/Bindings/Python/DialectNVGPU.cpp | 20 ++--- mlir/lib/Bindings/Python/DialectPDL.cpp | 43 +++++----- mlir/lib/Bindings/Python/DialectQuant.cpp | 79 +++++++++-------- .../Bindings/Python/DialectSparseTensor.cpp | 45 +++++----- mlir/lib/Bindings/Python/DialectTransform.cpp | 48 +++++------ .../Bindings/Python/ExecutionEngineModule.cpp | 85 ++++++++++--------- mlir/lib/Bindings/Python/GPUPasses.cpp | 5 +- mlir/lib/Bindings/Python/IRAffine.cpp | 7 +- mlir/lib/Bindings/Python/IRAttributes.cpp | 8 +- mlir/lib/Bindings/Python/IRCore.cpp | 10 +-- mlir/lib/Bindings/Python/IRInterfaces.cpp | 5 +- mlir/lib/Bindings/Python/IRModule.cpp | 6 +- mlir/lib/Bindings/Python/IRModule.h | 4 +- mlir/lib/Bindings/Python/IRTypes.cpp | 6 -- mlir/lib/Bindings/Python/LinalgPasses.cpp | 4 +- mlir/lib/Bindings/Python/MainModule.cpp | 3 +- mlir/lib/Bindings/Python/NanobindUtils.h | 5 +- mlir/lib/Bindings/Python/Pass.cpp | 7 +- .../Bindings/Python/RegisterEverything.cpp | 5 +- mlir/lib/Bindings/Python/Rewrite.cpp | 5 +- .../Bindings/Python/SparseTensorPasses.cpp | 4 +- .../Bindings/Python/TransformInterpreter.cpp | 44 +++++----- mlir/python/CMakeLists.txt | 22 +++-- .../python/dialects/sparse_tensor/dialect.py | 2 +- .../python/lib/PythonTestModuleNanobind.cpp | 4 +- .../llvm-project-overlay/mlir/BUILD.bazel | 23 ++--- 35 files changed, 357 insertions(+), 360 deletions(-) create mode 100644 mlir/include/mlir/Bindings/Python/Nanobind.h diff --git a/mlir/cmake/modules/AddMLIRPython.cmake b/mlir/cmake/modules/AddMLIRPython.cmake index 67619a90c90be9..53a70139fd5a68 100644 --- a/mlir/cmake/modules/AddMLIRPython.cmake +++ b/mlir/cmake/modules/AddMLIRPython.cmake @@ -661,6 +661,18 @@ function(add_mlir_python_extension libname extname) NB_DOMAIN mlir ${ARG_SOURCES} ) + + if (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL) + # Avoids warnings from upstream nanobind. + target_compile_options(nanobind-static + PRIVATE + -Wno-cast-qual + -Wno-zero-length-array + -Wno-nested-anon-types + -Wno-c++98-compat-extra-semi + -Wno-covered-switch-default + ) + endif() endif() # The extension itself must be compiled with RTTI and exceptions enabled. diff --git a/mlir/cmake/modules/MLIRDetectPythonEnv.cmake b/mlir/cmake/modules/MLIRDetectPythonEnv.cmake index d6bb65c64b8292..3a87d39c28a061 100644 --- a/mlir/cmake/modules/MLIRDetectPythonEnv.cmake +++ b/mlir/cmake/modules/MLIRDetectPythonEnv.cmake @@ -95,5 +95,17 @@ function(mlir_detect_nanobind_install) endif() message(STATUS "found (${PACKAGE_DIR})") set(nanobind_DIR "${PACKAGE_DIR}" PARENT_SCOPE) + execute_process( + COMMAND "${Python3_EXECUTABLE}" + -c "import nanobind;print(nanobind.include_dir(), end='')" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE PACKAGE_DIR + ERROR_QUIET) + if(NOT STATUS EQUAL "0") + message(STATUS "not found (install via 'pip install nanobind' or set nanobind_DIR)") + return() + endif() + set(nanobind_INCLUDE_DIR "${PACKAGE_DIR}" PARENT_SCOPE) endif() endfunction() diff --git a/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp b/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp index 6d83dc585dcd1d..189ebac368bf59 100644 --- a/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp +++ b/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp @@ -9,9 +9,8 @@ // //===----------------------------------------------------------------------===// -#include - #include "Standalone-c/Dialects.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "mlir/Bindings/Python/NanobindAdaptors.h" namespace nb = nanobind; diff --git a/mlir/include/mlir/Bindings/Python/Nanobind.h b/mlir/include/mlir/Bindings/Python/Nanobind.h new file mode 100644 index 00000000000000..ca942c83d3e2fa --- /dev/null +++ b/mlir/include/mlir/Bindings/Python/Nanobind.h @@ -0,0 +1,37 @@ +//===- Nanobind.h - Trampoline header with ignored warnings ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This file is a trampoline for the nanobind headers while disabling warnings +// reported by the LLVM/MLIR build. This file avoids adding complexity build +// system side. +//===----------------------------------------------------------------------===// + +#ifndef MLIR_BINDINGS_PYTHON_NANOBIND_H +#define MLIR_BINDINGS_PYTHON_NANOBIND_H + +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-length-array" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wnested-anon-types" +#pragma GCC diagnostic ignored "-Wc++98-compat-extra-semi" +#pragma GCC diagnostic ignored "-Wcovered-switch-default" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#endif // MLIR_BINDINGS_PYTHON_NANOBIND_H diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h index 943981b1fa03dd..517351cac6dbce 100644 --- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h +++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h @@ -19,14 +19,12 @@ #ifndef MLIR_BINDINGS_PYTHON_NANOBINDADAPTORS_H #define MLIR_BINDINGS_PYTHON_NANOBINDADAPTORS_H -#include -#include - #include -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/Diagnostics.h" #include "mlir-c/IR.h" +#include "mlir/Bindings/Python/Nanobind.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. #include "llvm/ADT/Twine.h" // Raw CAPI type casters need to be declared before use, so always include them @@ -631,40 +629,6 @@ class mlir_value_subclass : public pure_subclass { } // namespace nanobind_adaptors -/// RAII scope intercepting all diagnostics into a string. The message must be -/// checked before this goes out of scope. -class CollectDiagnosticsToStringScope { -public: - explicit CollectDiagnosticsToStringScope(MlirContext ctx) : context(ctx) { - handlerID = mlirContextAttachDiagnosticHandler(ctx, &handler, &errorMessage, - /*deleteUserData=*/nullptr); - } - ~CollectDiagnosticsToStringScope() { - assert(errorMessage.empty() && "unchecked error message"); - mlirContextDetachDiagnosticHandler(context, handlerID); - } - - [[nodiscard]] std::string takeMessage() { return std::move(errorMessage); } - -private: - static MlirLogicalResult handler(MlirDiagnostic diag, void *data) { - auto printer = +[](MlirStringRef message, void *data) { - *static_cast(data) += - llvm::StringRef(message.data, message.length); - }; - MlirLocation loc = mlirDiagnosticGetLocation(diag); - *static_cast(data) += "at "; - mlirLocationPrint(loc, printer, data); - *static_cast(data) += ": "; - mlirDiagnosticPrint(diag, printer, data); - return mlirLogicalResultSuccess(); - } - - MlirContext context; - MlirDiagnosticHandlerID handlerID; - std::string errorMessage = ""; -}; - } // namespace python } // namespace mlir diff --git a/mlir/lib/Bindings/Python/AsyncPasses.cpp b/mlir/lib/Bindings/Python/AsyncPasses.cpp index b611a758dbbb37..cfb8dcaaa72ae3 100644 --- a/mlir/lib/Bindings/Python/AsyncPasses.cpp +++ b/mlir/lib/Bindings/Python/AsyncPasses.cpp @@ -8,14 +8,13 @@ #include "mlir-c/Dialect/Async.h" -#include -#include +#include "mlir/Bindings/Python/Nanobind.h" // ----------------------------------------------------------------------------- // Module initialization. // ----------------------------------------------------------------------------- -PYBIND11_MODULE(_mlirAsyncPasses, m) { +NB_MODULE(_mlirAsyncPasses, m) { m.doc() = "MLIR Async Dialect Passes"; // Register all Async passes on load. diff --git a/mlir/lib/Bindings/Python/DialectGPU.cpp b/mlir/lib/Bindings/Python/DialectGPU.cpp index 560a54bcd15919..e5045cf0bba354 100644 --- a/mlir/lib/Bindings/Python/DialectGPU.cpp +++ b/mlir/lib/Bindings/Python/DialectGPU.cpp @@ -9,21 +9,21 @@ #include "mlir-c/Dialect/GPU.h" #include "mlir-c/IR.h" #include "mlir-c/Support.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -#include -#include +namespace nb = nanobind; +using namespace nanobind::literals; -namespace py = pybind11; using namespace mlir; using namespace mlir::python; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; // ----------------------------------------------------------------------------- // Module initialization. // ----------------------------------------------------------------------------- -PYBIND11_MODULE(_mlirDialectsGPU, m) { +NB_MODULE(_mlirDialectsGPU, m) { m.doc() = "MLIR GPU Dialect"; //===-------------------------------------------------------------------===// // AsyncTokenType @@ -34,11 +34,11 @@ PYBIND11_MODULE(_mlirDialectsGPU, m) { mlirGPUAsyncTokenType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirGPUAsyncTokenTypeGet(ctx)); }, - "Gets an instance of AsyncTokenType in the same context", py::arg("cls"), - py::arg("ctx") = py::none()); + "Gets an instance of AsyncTokenType in the same context", nb::arg("cls"), + nb::arg("ctx").none() = nb::none()); //===-------------------------------------------------------------------===// // ObjectAttr @@ -47,12 +47,12 @@ PYBIND11_MODULE(_mlirDialectsGPU, m) { mlir_attribute_subclass(m, "ObjectAttr", mlirAttributeIsAGPUObjectAttr) .def_classmethod( "get", - [](py::object cls, MlirAttribute target, uint32_t format, - py::bytes object, std::optional mlirObjectProps, + [](nb::object cls, MlirAttribute target, uint32_t format, + nb::bytes object, std::optional mlirObjectProps, std::optional mlirKernelsAttr) { - py::buffer_info info(py::buffer(object).request()); - MlirStringRef objectStrRef = - mlirStringRefCreate(static_cast(info.ptr), info.size); + MlirStringRef objectStrRef = mlirStringRefCreate( + static_cast(const_cast(object.data())), + object.size()); return cls(mlirGPUObjectAttrGetWithKernels( mlirAttributeGetContext(target), target, format, objectStrRef, mlirObjectProps.has_value() ? *mlirObjectProps @@ -61,7 +61,7 @@ PYBIND11_MODULE(_mlirDialectsGPU, m) { : MlirAttribute{nullptr})); }, "cls"_a, "target"_a, "format"_a, "object"_a, - "properties"_a = py::none(), "kernels"_a = py::none(), + "properties"_a.none() = nb::none(), "kernels"_a.none() = nb::none(), "Gets a gpu.object from parameters.") .def_property_readonly( "target", @@ -73,18 +73,18 @@ PYBIND11_MODULE(_mlirDialectsGPU, m) { "object", [](MlirAttribute self) { MlirStringRef stringRef = mlirGPUObjectAttrGetObject(self); - return py::bytes(stringRef.data, stringRef.length); + return nb::bytes(stringRef.data, stringRef.length); }) .def_property_readonly("properties", - [](MlirAttribute self) { + [](MlirAttribute self) -> nb::object { if (mlirGPUObjectAttrHasProperties(self)) - return py::cast( + return nb::cast( mlirGPUObjectAttrGetProperties(self)); - return py::none().cast(); + return nb::none(); }) - .def_property_readonly("kernels", [](MlirAttribute self) { + .def_property_readonly("kernels", [](MlirAttribute self) -> nb::object { if (mlirGPUObjectAttrHasKernels(self)) - return py::cast(mlirGPUObjectAttrGetKernels(self)); - return py::none().cast(); + return nb::cast(mlirGPUObjectAttrGetKernels(self)); + return nb::none(); }); } diff --git a/mlir/lib/Bindings/Python/DialectLLVM.cpp b/mlir/lib/Bindings/Python/DialectLLVM.cpp index cccf1370b8cc87..f211e769d66bec 100644 --- a/mlir/lib/Bindings/Python/DialectLLVM.cpp +++ b/mlir/lib/Bindings/Python/DialectLLVM.cpp @@ -12,15 +12,19 @@ #include "mlir-c/IR.h" #include "mlir-c/Support.h" #include "mlir/Bindings/Python/Diagnostics.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" + +namespace nb = nanobind; + +using namespace nanobind::literals; -namespace py = pybind11; using namespace llvm; using namespace mlir; using namespace mlir::python; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -void populateDialectLLVMSubmodule(const pybind11::module &m) { +void populateDialectLLVMSubmodule(const nanobind::module_ &m) { //===--------------------------------------------------------------------===// // StructType @@ -31,35 +35,35 @@ void populateDialectLLVMSubmodule(const pybind11::module &m) { llvmStructType.def_classmethod( "get_literal", - [](py::object cls, const std::vector &elements, bool packed, + [](nb::object cls, const std::vector &elements, bool packed, MlirLocation loc) { CollectDiagnosticsToStringScope scope(mlirLocationGetContext(loc)); MlirType type = mlirLLVMStructTypeLiteralGetChecked( loc, elements.size(), elements.data(), packed); if (mlirTypeIsNull(type)) { - throw py::value_error(scope.takeMessage()); + throw nb::value_error(scope.takeMessage().c_str()); } return cls(type); }, - "cls"_a, "elements"_a, py::kw_only(), "packed"_a = false, - "loc"_a = py::none()); + "cls"_a, "elements"_a, nb::kw_only(), "packed"_a = false, + "loc"_a.none() = nb::none()); llvmStructType.def_classmethod( "get_identified", - [](py::object cls, const std::string &name, MlirContext context) { + [](nb::object cls, const std::string &name, MlirContext context) { return cls(mlirLLVMStructTypeIdentifiedGet( context, mlirStringRefCreate(name.data(), name.size()))); }, - "cls"_a, "name"_a, py::kw_only(), "context"_a = py::none()); + "cls"_a, "name"_a, nb::kw_only(), "context"_a.none() = nb::none()); llvmStructType.def_classmethod( "get_opaque", - [](py::object cls, const std::string &name, MlirContext context) { + [](nb::object cls, const std::string &name, MlirContext context) { return cls(mlirLLVMStructTypeOpaqueGet( context, mlirStringRefCreate(name.data(), name.size()))); }, - "cls"_a, "name"_a, "context"_a = py::none()); + "cls"_a, "name"_a, "context"_a.none() = nb::none()); llvmStructType.def( "set_body", @@ -67,22 +71,22 @@ void populateDialectLLVMSubmodule(const pybind11::module &m) { MlirLogicalResult result = mlirLLVMStructTypeSetBody( self, elements.size(), elements.data(), packed); if (!mlirLogicalResultIsSuccess(result)) { - throw py::value_error( + throw nb::value_error( "Struct body already set to different content."); } }, - "elements"_a, py::kw_only(), "packed"_a = false); + "elements"_a, nb::kw_only(), "packed"_a = false); llvmStructType.def_classmethod( "new_identified", - [](py::object cls, const std::string &name, + [](nb::object cls, const std::string &name, const std::vector &elements, bool packed, MlirContext ctx) { return cls(mlirLLVMStructTypeIdentifiedNewGet( ctx, mlirStringRefCreate(name.data(), name.length()), elements.size(), elements.data(), packed)); }, - "cls"_a, "name"_a, "elements"_a, py::kw_only(), "packed"_a = false, - "context"_a = py::none()); + "cls"_a, "name"_a, "elements"_a, nb::kw_only(), "packed"_a = false, + "context"_a.none() = nb::none()); llvmStructType.def_property_readonly( "name", [](MlirType type) -> std::optional { @@ -93,12 +97,12 @@ void populateDialectLLVMSubmodule(const pybind11::module &m) { return StringRef(stringRef.data, stringRef.length).str(); }); - llvmStructType.def_property_readonly("body", [](MlirType type) -> py::object { + llvmStructType.def_property_readonly("body", [](MlirType type) -> nb::object { // Don't crash in absence of a body. if (mlirLLVMStructTypeIsOpaque(type)) - return py::none(); + return nb::none(); - py::list body; + nb::list body; for (intptr_t i = 0, e = mlirLLVMStructTypeGetNumElementTypes(type); i < e; ++i) { body.append(mlirLLVMStructTypeGetElementType(type, i)); @@ -119,24 +123,24 @@ void populateDialectLLVMSubmodule(const pybind11::module &m) { mlir_type_subclass(m, "PointerType", mlirTypeIsALLVMPointerType) .def_classmethod( "get", - [](py::object cls, std::optional addressSpace, + [](nb::object cls, std::optional addressSpace, MlirContext context) { CollectDiagnosticsToStringScope scope(context); MlirType type = mlirLLVMPointerTypeGet( context, addressSpace.has_value() ? *addressSpace : 0); if (mlirTypeIsNull(type)) { - throw py::value_error(scope.takeMessage()); + throw nb::value_error(scope.takeMessage().c_str()); } return cls(type); }, - "cls"_a, "address_space"_a = py::none(), py::kw_only(), - "context"_a = py::none()) + "cls"_a, "address_space"_a.none() = nb::none(), nb::kw_only(), + "context"_a.none() = nb::none()) .def_property_readonly("address_space", [](MlirType type) { return mlirLLVMPointerTypeGetAddressSpace(type); }); } -PYBIND11_MODULE(_mlirDialectsLLVM, m) { +NB_MODULE(_mlirDialectsLLVM, m) { m.doc() = "MLIR LLVM Dialect"; populateDialectLLVMSubmodule(m); diff --git a/mlir/lib/Bindings/Python/DialectLinalg.cpp b/mlir/lib/Bindings/Python/DialectLinalg.cpp index 2e54ebeb61fb10..548df4ee100aa9 100644 --- a/mlir/lib/Bindings/Python/DialectLinalg.cpp +++ b/mlir/lib/Bindings/Python/DialectLinalg.cpp @@ -8,20 +8,21 @@ #include "mlir-c/Dialect/Linalg.h" #include "mlir-c/IR.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; -static void populateDialectLinalgSubmodule(py::module m) { +static void populateDialectLinalgSubmodule(nb::module_ m) { m.def( "fill_builtin_region", [](MlirOperation op) { mlirLinalgFillBuiltinNamedOpRegion(op); }, - py::arg("op"), + nb::arg("op"), "Fill the region for `op`, which is assumed to be a builtin named Linalg " "op."); } -PYBIND11_MODULE(_mlirDialectsLinalg, m) { +NB_MODULE(_mlirDialectsLinalg, m) { m.doc() = "MLIR Linalg dialect."; populateDialectLinalgSubmodule(m); diff --git a/mlir/lib/Bindings/Python/DialectNVGPU.cpp b/mlir/lib/Bindings/Python/DialectNVGPU.cpp index 754e0a75b0abc7..a0d6a4b4c73f92 100644 --- a/mlir/lib/Bindings/Python/DialectNVGPU.cpp +++ b/mlir/lib/Bindings/Python/DialectNVGPU.cpp @@ -8,33 +8,33 @@ #include "mlir-c/Dialect/NVGPU.h" #include "mlir-c/IR.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" -#include +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; using namespace llvm; using namespace mlir; using namespace mlir::python; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -static void populateDialectNVGPUSubmodule(const pybind11::module &m) { +static void populateDialectNVGPUSubmodule(const nb::module_ &m) { auto nvgpuTensorMapDescriptorType = mlir_type_subclass( m, "TensorMapDescriptorType", mlirTypeIsANVGPUTensorMapDescriptorType); nvgpuTensorMapDescriptorType.def_classmethod( "get", - [](py::object cls, MlirType tensorMemrefType, int swizzle, int l2promo, + [](nb::object cls, MlirType tensorMemrefType, int swizzle, int l2promo, int oobFill, int interleave, MlirContext ctx) { return cls(mlirNVGPUTensorMapDescriptorTypeGet( ctx, tensorMemrefType, swizzle, l2promo, oobFill, interleave)); }, "Gets an instance of TensorMapDescriptorType in the same context", - py::arg("cls"), py::arg("tensor_type"), py::arg("swizzle"), - py::arg("l2promo"), py::arg("oob_fill"), py::arg("interleave"), - py::arg("ctx") = py::none()); + nb::arg("cls"), nb::arg("tensor_type"), nb::arg("swizzle"), + nb::arg("l2promo"), nb::arg("oob_fill"), nb::arg("interleave"), + nb::arg("ctx").none() = nb::none()); } -PYBIND11_MODULE(_mlirDialectsNVGPU, m) { +NB_MODULE(_mlirDialectsNVGPU, m) { m.doc() = "MLIR NVGPU dialect."; populateDialectNVGPUSubmodule(m); diff --git a/mlir/lib/Bindings/Python/DialectPDL.cpp b/mlir/lib/Bindings/Python/DialectPDL.cpp index 8d3f9a7ab1d6ac..bcc6ff406c9529 100644 --- a/mlir/lib/Bindings/Python/DialectPDL.cpp +++ b/mlir/lib/Bindings/Python/DialectPDL.cpp @@ -8,19 +8,16 @@ #include "mlir-c/Dialect/PDL.h" #include "mlir-c/IR.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" -#include -#include -#include -#include +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; using namespace llvm; using namespace mlir; using namespace mlir::python; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -void populateDialectPDLSubmodule(const pybind11::module &m) { +void populateDialectPDLSubmodule(const nanobind::module_ &m) { //===-------------------------------------------------------------------===// // PDLType //===-------------------------------------------------------------------===// @@ -35,11 +32,11 @@ void populateDialectPDLSubmodule(const pybind11::module &m) { mlir_type_subclass(m, "AttributeType", mlirTypeIsAPDLAttributeType); attributeType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirPDLAttributeTypeGet(ctx)); }, - "Get an instance of AttributeType in given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of AttributeType in given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // OperationType @@ -49,11 +46,11 @@ void populateDialectPDLSubmodule(const pybind11::module &m) { mlir_type_subclass(m, "OperationType", mlirTypeIsAPDLOperationType); operationType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirPDLOperationTypeGet(ctx)); }, - "Get an instance of OperationType in given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of OperationType in given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // RangeType @@ -62,12 +59,12 @@ void populateDialectPDLSubmodule(const pybind11::module &m) { auto rangeType = mlir_type_subclass(m, "RangeType", mlirTypeIsAPDLRangeType); rangeType.def_classmethod( "get", - [](py::object cls, MlirType elementType) { + [](nb::object cls, MlirType elementType) { return cls(mlirPDLRangeTypeGet(elementType)); }, "Gets an instance of RangeType in the same context as the provided " "element type.", - py::arg("cls"), py::arg("element_type")); + nb::arg("cls"), nb::arg("element_type")); rangeType.def_property_readonly( "element_type", [](MlirType type) { return mlirPDLRangeTypeGetElementType(type); }, @@ -80,11 +77,11 @@ void populateDialectPDLSubmodule(const pybind11::module &m) { auto typeType = mlir_type_subclass(m, "TypeType", mlirTypeIsAPDLTypeType); typeType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirPDLTypeTypeGet(ctx)); }, - "Get an instance of TypeType in given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of TypeType in given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // ValueType @@ -93,14 +90,14 @@ void populateDialectPDLSubmodule(const pybind11::module &m) { auto valueType = mlir_type_subclass(m, "ValueType", mlirTypeIsAPDLValueType); valueType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirPDLValueTypeGet(ctx)); }, - "Get an instance of TypeType in given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of TypeType in given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); } -PYBIND11_MODULE(_mlirDialectsPDL, m) { +NB_MODULE(_mlirDialectsPDL, m) { m.doc() = "MLIR PDL dialect."; populateDialectPDLSubmodule(m); } diff --git a/mlir/lib/Bindings/Python/DialectQuant.cpp b/mlir/lib/Bindings/Python/DialectQuant.cpp index 9a871f2c122d12..29f19c9c500659 100644 --- a/mlir/lib/Bindings/Python/DialectQuant.cpp +++ b/mlir/lib/Bindings/Python/DialectQuant.cpp @@ -6,21 +6,20 @@ // //===----------------------------------------------------------------------===// -#include "mlir-c/Dialect/Quant.h" -#include "mlir-c/IR.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" #include -#include -#include -#include #include -namespace py = pybind11; +#include "mlir-c/Dialect/Quant.h" +#include "mlir-c/IR.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" + +namespace nb = nanobind; using namespace llvm; using namespace mlir; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -static void populateDialectQuantSubmodule(const py::module &m) { +static void populateDialectQuantSubmodule(const nb::module_ &m) { //===-------------------------------------------------------------------===// // QuantizedType //===-------------------------------------------------------------------===// @@ -35,7 +34,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Default minimum value for the integer with the specified signedness and " "bit width.", - py::arg("is_signed"), py::arg("integral_width")); + nb::arg("is_signed"), nb::arg("integral_width")); quantizedType.def_staticmethod( "default_maximum_for_integer", [](bool isSigned, unsigned integralWidth) { @@ -44,7 +43,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Default maximum value for the integer with the specified signedness and " "bit width.", - py::arg("is_signed"), py::arg("integral_width")); + nb::arg("is_signed"), nb::arg("integral_width")); quantizedType.def_property_readonly( "expressed_type", [](MlirType type) { return mlirQuantizedTypeGetExpressedType(type); }, @@ -82,7 +81,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Checks whether the candidate type can be expressed by this quantized " "type.", - py::arg("candidate")); + nb::arg("candidate")); quantizedType.def_property_readonly( "quantized_element_type", [](MlirType type) { @@ -96,24 +95,24 @@ static void populateDialectQuantSubmodule(const py::module &m) { mlirQuantizedTypeCastFromStorageType(type, candidate); if (!mlirTypeIsNull(castResult)) return castResult; - throw py::type_error("Invalid cast."); + throw nb::type_error("Invalid cast."); }, "Casts from a type based on the storage type of this quantized type to a " "corresponding type based on the quantized type. Raises TypeError if the " "cast is not valid.", - py::arg("candidate")); + nb::arg("candidate")); quantizedType.def_staticmethod( "cast_to_storage_type", [](MlirType type) { MlirType castResult = mlirQuantizedTypeCastToStorageType(type); if (!mlirTypeIsNull(castResult)) return castResult; - throw py::type_error("Invalid cast."); + throw nb::type_error("Invalid cast."); }, "Casts from a type based on a quantized type to a corresponding type " "based on the storage type of this quantized type. Raises TypeError if " "the cast is not valid.", - py::arg("type")); + nb::arg("type")); quantizedType.def( "cast_from_expressed_type", [](MlirType type, MlirType candidate) { @@ -121,24 +120,24 @@ static void populateDialectQuantSubmodule(const py::module &m) { mlirQuantizedTypeCastFromExpressedType(type, candidate); if (!mlirTypeIsNull(castResult)) return castResult; - throw py::type_error("Invalid cast."); + throw nb::type_error("Invalid cast."); }, "Casts from a type based on the expressed type of this quantized type to " "a corresponding type based on the quantized type. Raises TypeError if " "the cast is not valid.", - py::arg("candidate")); + nb::arg("candidate")); quantizedType.def_staticmethod( "cast_to_expressed_type", [](MlirType type) { MlirType castResult = mlirQuantizedTypeCastToExpressedType(type); if (!mlirTypeIsNull(castResult)) return castResult; - throw py::type_error("Invalid cast."); + throw nb::type_error("Invalid cast."); }, "Casts from a type based on a quantized type to a corresponding type " "based on the expressed type of this quantized type. Raises TypeError if " "the cast is not valid.", - py::arg("type")); + nb::arg("type")); quantizedType.def( "cast_expressed_to_storage_type", [](MlirType type, MlirType candidate) { @@ -146,12 +145,12 @@ static void populateDialectQuantSubmodule(const py::module &m) { mlirQuantizedTypeCastExpressedToStorageType(type, candidate); if (!mlirTypeIsNull(castResult)) return castResult; - throw py::type_error("Invalid cast."); + throw nb::type_error("Invalid cast."); }, "Casts from a type based on the expressed type of this quantized type to " "a corresponding type based on the storage type. Raises TypeError if the " "cast is not valid.", - py::arg("candidate")); + nb::arg("candidate")); quantizedType.get_class().attr("FLAG_SIGNED") = mlirQuantizedTypeGetSignedFlag(); @@ -165,7 +164,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { quantizedType.get_class()); anyQuantizedType.def_classmethod( "get", - [](py::object cls, unsigned flags, MlirType storageType, + [](nb::object cls, unsigned flags, MlirType storageType, MlirType expressedType, int64_t storageTypeMin, int64_t storageTypeMax) { return cls(mlirAnyQuantizedTypeGet(flags, storageType, expressedType, @@ -173,9 +172,9 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Gets an instance of AnyQuantizedType in the same context as the " "provided storage type.", - py::arg("cls"), py::arg("flags"), py::arg("storage_type"), - py::arg("expressed_type"), py::arg("storage_type_min"), - py::arg("storage_type_max")); + nb::arg("cls"), nb::arg("flags"), nb::arg("storage_type"), + nb::arg("expressed_type"), nb::arg("storage_type_min"), + nb::arg("storage_type_max")); //===-------------------------------------------------------------------===// // UniformQuantizedType @@ -186,7 +185,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { quantizedType.get_class()); uniformQuantizedType.def_classmethod( "get", - [](py::object cls, unsigned flags, MlirType storageType, + [](nb::object cls, unsigned flags, MlirType storageType, MlirType expressedType, double scale, int64_t zeroPoint, int64_t storageTypeMin, int64_t storageTypeMax) { return cls(mlirUniformQuantizedTypeGet(flags, storageType, @@ -195,9 +194,9 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Gets an instance of UniformQuantizedType in the same context as the " "provided storage type.", - py::arg("cls"), py::arg("flags"), py::arg("storage_type"), - py::arg("expressed_type"), py::arg("scale"), py::arg("zero_point"), - py::arg("storage_type_min"), py::arg("storage_type_max")); + nb::arg("cls"), nb::arg("flags"), nb::arg("storage_type"), + nb::arg("expressed_type"), nb::arg("scale"), nb::arg("zero_point"), + nb::arg("storage_type_min"), nb::arg("storage_type_max")); uniformQuantizedType.def_property_readonly( "scale", [](MlirType type) { return mlirUniformQuantizedTypeGetScale(type); }, @@ -221,12 +220,12 @@ static void populateDialectQuantSubmodule(const py::module &m) { quantizedType.get_class()); uniformQuantizedPerAxisType.def_classmethod( "get", - [](py::object cls, unsigned flags, MlirType storageType, + [](nb::object cls, unsigned flags, MlirType storageType, MlirType expressedType, std::vector scales, std::vector zeroPoints, int32_t quantizedDimension, int64_t storageTypeMin, int64_t storageTypeMax) { if (scales.size() != zeroPoints.size()) - throw py::value_error( + throw nb::value_error( "Mismatching number of scales and zero points."); auto nDims = static_cast(scales.size()); return cls(mlirUniformQuantizedPerAxisTypeGet( @@ -236,10 +235,10 @@ static void populateDialectQuantSubmodule(const py::module &m) { }, "Gets an instance of UniformQuantizedPerAxisType in the same context as " "the provided storage type.", - py::arg("cls"), py::arg("flags"), py::arg("storage_type"), - py::arg("expressed_type"), py::arg("scales"), py::arg("zero_points"), - py::arg("quantized_dimension"), py::arg("storage_type_min"), - py::arg("storage_type_max")); + nb::arg("cls"), nb::arg("flags"), nb::arg("storage_type"), + nb::arg("expressed_type"), nb::arg("scales"), nb::arg("zero_points"), + nb::arg("quantized_dimension"), nb::arg("storage_type_min"), + nb::arg("storage_type_max")); uniformQuantizedPerAxisType.def_property_readonly( "scales", [](MlirType type) { @@ -294,13 +293,13 @@ static void populateDialectQuantSubmodule(const py::module &m) { quantizedType.get_class()); calibratedQuantizedType.def_classmethod( "get", - [](py::object cls, MlirType expressedType, double min, double max) { + [](nb::object cls, MlirType expressedType, double min, double max) { return cls(mlirCalibratedQuantizedTypeGet(expressedType, min, max)); }, "Gets an instance of CalibratedQuantizedType in the same context as the " "provided expressed type.", - py::arg("cls"), py::arg("expressed_type"), py::arg("min"), - py::arg("max")); + nb::arg("cls"), nb::arg("expressed_type"), nb::arg("min"), + nb::arg("max")); calibratedQuantizedType.def_property_readonly("min", [](MlirType type) { return mlirCalibratedQuantizedTypeGetMin(type); }); @@ -309,7 +308,7 @@ static void populateDialectQuantSubmodule(const py::module &m) { }); } -PYBIND11_MODULE(_mlirDialectsQuant, m) { +NB_MODULE(_mlirDialectsQuant, m) { m.doc() = "MLIR Quantization dialect"; populateDialectQuantSubmodule(m); diff --git a/mlir/lib/Bindings/Python/DialectSparseTensor.cpp b/mlir/lib/Bindings/Python/DialectSparseTensor.cpp index a730bf500be98c..97cebcceebd9ad 100644 --- a/mlir/lib/Bindings/Python/DialectSparseTensor.cpp +++ b/mlir/lib/Bindings/Python/DialectSparseTensor.cpp @@ -6,32 +6,30 @@ // //===----------------------------------------------------------------------===// +#include +#include + #include "mlir-c/AffineMap.h" #include "mlir-c/Dialect/SparseTensor.h" #include "mlir-c/IR.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" -#include -#include -#include -#include -#include -#include +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; using namespace llvm; using namespace mlir; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -static void populateDialectSparseTensorSubmodule(const py::module &m) { - py::enum_(m, "LevelFormat", py::module_local()) +static void populateDialectSparseTensorSubmodule(const nb::module_ &m) { + nb::enum_(m, "LevelFormat", nb::is_arithmetic(), + nb::is_flag()) .value("dense", MLIR_SPARSE_TENSOR_LEVEL_DENSE) .value("n_out_of_m", MLIR_SPARSE_TENSOR_LEVEL_N_OUT_OF_M) .value("compressed", MLIR_SPARSE_TENSOR_LEVEL_COMPRESSED) .value("singleton", MLIR_SPARSE_TENSOR_LEVEL_SINGLETON) .value("loose_compressed", MLIR_SPARSE_TENSOR_LEVEL_LOOSE_COMPRESSED); - py::enum_(m, "LevelProperty", - py::module_local()) + nb::enum_(m, "LevelProperty") .value("non_ordered", MLIR_SPARSE_PROPERTY_NON_ORDERED) .value("non_unique", MLIR_SPARSE_PROPERTY_NON_UNIQUE) .value("soa", MLIR_SPARSE_PROPERTY_SOA); @@ -40,7 +38,7 @@ static void populateDialectSparseTensorSubmodule(const py::module &m) { mlirAttributeIsASparseTensorEncodingAttr) .def_classmethod( "get", - [](py::object cls, std::vector lvlTypes, + [](nb::object cls, std::vector lvlTypes, std::optional dimToLvl, std::optional lvlToDim, int posWidth, int crdWidth, std::optional explicitVal, @@ -52,24 +50,25 @@ static void populateDialectSparseTensorSubmodule(const py::module &m) { crdWidth, explicitVal ? *explicitVal : MlirAttribute{nullptr}, implicitVal ? *implicitVal : MlirAttribute{nullptr})); }, - py::arg("cls"), py::arg("lvl_types"), py::arg("dim_to_lvl"), - py::arg("lvl_to_dim"), py::arg("pos_width"), py::arg("crd_width"), - py::arg("explicit_val") = py::none(), - py::arg("implicit_val") = py::none(), py::arg("context") = py::none(), + nb::arg("cls"), nb::arg("lvl_types"), nb::arg("dim_to_lvl").none(), + nb::arg("lvl_to_dim").none(), nb::arg("pos_width"), + nb::arg("crd_width"), nb::arg("explicit_val").none() = nb::none(), + nb::arg("implicit_val").none() = nb::none(), + nb::arg("context").none() = nb::none(), "Gets a sparse_tensor.encoding from parameters.") .def_classmethod( "build_level_type", - [](py::object cls, MlirSparseTensorLevelFormat lvlFmt, + [](nb::object cls, MlirSparseTensorLevelFormat lvlFmt, const std::vector &properties, unsigned n, unsigned m) { return mlirSparseTensorEncodingAttrBuildLvlType( lvlFmt, properties.data(), properties.size(), n, m); }, - py::arg("cls"), py::arg("lvl_fmt"), - py::arg("properties") = + nb::arg("cls"), nb::arg("lvl_fmt"), + nb::arg("properties") = std::vector(), - py::arg("n") = 0, py::arg("m") = 0, + nb::arg("n") = 0, nb::arg("m") = 0, "Builds a sparse_tensor.encoding.level_type from parameters.") .def_property_readonly( "lvl_types", @@ -143,7 +142,7 @@ static void populateDialectSparseTensorSubmodule(const py::module &m) { }); } -PYBIND11_MODULE(_mlirDialectsSparseTensor, m) { +NB_MODULE(_mlirDialectsSparseTensor, m) { m.doc() = "MLIR SparseTensor dialect."; populateDialectSparseTensorSubmodule(m); } diff --git a/mlir/lib/Bindings/Python/DialectTransform.cpp b/mlir/lib/Bindings/Python/DialectTransform.cpp index 6b57e652aa9d8b..59a030ac67f570 100644 --- a/mlir/lib/Bindings/Python/DialectTransform.cpp +++ b/mlir/lib/Bindings/Python/DialectTransform.cpp @@ -6,22 +6,20 @@ // //===----------------------------------------------------------------------===// +#include + #include "mlir-c/Dialect/Transform.h" #include "mlir-c/IR.h" #include "mlir-c/Support.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" -#include -#include -#include -#include -#include +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; using namespace mlir; using namespace mlir::python; -using namespace mlir::python::adaptors; +using namespace mlir::python::nanobind_adaptors; -void populateDialectTransformSubmodule(const pybind11::module &m) { +void populateDialectTransformSubmodule(const nb::module_ &m) { //===-------------------------------------------------------------------===// // AnyOpType //===-------------------------------------------------------------------===// @@ -31,11 +29,11 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { mlirTransformAnyOpTypeGetTypeID); anyOpType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirTransformAnyOpTypeGet(ctx)); }, - "Get an instance of AnyOpType in the given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of AnyOpType in the given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // AnyParamType @@ -46,11 +44,11 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { mlirTransformAnyParamTypeGetTypeID); anyParamType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirTransformAnyParamTypeGet(ctx)); }, - "Get an instance of AnyParamType in the given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of AnyParamType in the given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // AnyValueType @@ -61,11 +59,11 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { mlirTransformAnyValueTypeGetTypeID); anyValueType.def_classmethod( "get", - [](py::object cls, MlirContext ctx) { + [](nb::object cls, MlirContext ctx) { return cls(mlirTransformAnyValueTypeGet(ctx)); }, - "Get an instance of AnyValueType in the given context.", py::arg("cls"), - py::arg("context") = py::none()); + "Get an instance of AnyValueType in the given context.", nb::arg("cls"), + nb::arg("context").none() = nb::none()); //===-------------------------------------------------------------------===// // OperationType @@ -76,21 +74,21 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { mlirTransformOperationTypeGetTypeID); operationType.def_classmethod( "get", - [](py::object cls, const std::string &operationName, MlirContext ctx) { + [](nb::object cls, const std::string &operationName, MlirContext ctx) { MlirStringRef cOperationName = mlirStringRefCreate(operationName.data(), operationName.size()); return cls(mlirTransformOperationTypeGet(ctx, cOperationName)); }, "Get an instance of OperationType for the given kind in the given " "context", - py::arg("cls"), py::arg("operation_name"), - py::arg("context") = py::none()); + nb::arg("cls"), nb::arg("operation_name"), + nb::arg("context").none() = nb::none()); operationType.def_property_readonly( "operation_name", [](MlirType type) { MlirStringRef operationName = mlirTransformOperationTypeGetOperationName(type); - return py::str(operationName.data, operationName.length); + return nb::str(operationName.data, operationName.length); }, "Get the name of the payload operation accepted by the handle."); @@ -103,11 +101,11 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { mlirTransformParamTypeGetTypeID); paramType.def_classmethod( "get", - [](py::object cls, MlirType type, MlirContext ctx) { + [](nb::object cls, MlirType type, MlirContext ctx) { return cls(mlirTransformParamTypeGet(ctx, type)); }, "Get an instance of ParamType for the given type in the given context.", - py::arg("cls"), py::arg("type"), py::arg("context") = py::none()); + nb::arg("cls"), nb::arg("type"), nb::arg("context").none() = nb::none()); paramType.def_property_readonly( "type", [](MlirType type) { @@ -117,7 +115,7 @@ void populateDialectTransformSubmodule(const pybind11::module &m) { "Get the type this ParamType is associated with."); } -PYBIND11_MODULE(_mlirDialectsTransform, m) { +NB_MODULE(_mlirDialectsTransform, m) { m.doc() = "MLIR Transform dialect."; populateDialectTransformSubmodule(m); } diff --git a/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp b/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp index b3df30583fc963..81dada3553622b 100644 --- a/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp +++ b/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp @@ -7,9 +7,10 @@ //===----------------------------------------------------------------------===// #include "mlir-c/ExecutionEngine.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; using namespace mlir; using namespace mlir::python; @@ -34,23 +35,22 @@ class PyExecutionEngine { executionEngine.ptr = nullptr; referencedObjects.clear(); } - pybind11::object getCapsule() { - return py::reinterpret_steal( - mlirPythonExecutionEngineToCapsule(get())); + nb::object getCapsule() { + return nb::steal(mlirPythonExecutionEngineToCapsule(get())); } // Add an object to the list of referenced objects whose lifetime must exceed // those of the ExecutionEngine. - void addReferencedObject(const pybind11::object &obj) { + void addReferencedObject(const nb::object &obj) { referencedObjects.push_back(obj); } - static pybind11::object createFromCapsule(pybind11::object capsule) { + static nb::object createFromCapsule(nb::object capsule) { MlirExecutionEngine rawPm = mlirPythonCapsuleToExecutionEngine(capsule.ptr()); if (mlirExecutionEngineIsNull(rawPm)) - throw py::error_already_set(); - return py::cast(PyExecutionEngine(rawPm), py::return_value_policy::move); + throw nb::python_error(); + return nb::cast(PyExecutionEngine(rawPm), nb::rv_policy::move); } private: @@ -58,44 +58,45 @@ class PyExecutionEngine { // We support Python ctypes closures as callbacks. Keep a list of the objects // so that they don't get garbage collected. (The ExecutionEngine itself // just holds raw pointers with no lifetime semantics). - std::vector referencedObjects; + std::vector referencedObjects; }; } // namespace /// Create the `mlir.execution_engine` module here. -PYBIND11_MODULE(_mlirExecutionEngine, m) { +NB_MODULE(_mlirExecutionEngine, m) { m.doc() = "MLIR Execution Engine"; //---------------------------------------------------------------------------- // Mapping of the top-level PassManager //---------------------------------------------------------------------------- - py::class_(m, "ExecutionEngine", py::module_local()) - .def(py::init<>([](MlirModule module, int optLevel, - const std::vector &sharedLibPaths, - bool enableObjectDump) { - llvm::SmallVector libPaths; - for (const std::string &path : sharedLibPaths) - libPaths.push_back({path.c_str(), path.length()}); - MlirExecutionEngine executionEngine = - mlirExecutionEngineCreate(module, optLevel, libPaths.size(), - libPaths.data(), enableObjectDump); - if (mlirExecutionEngineIsNull(executionEngine)) - throw std::runtime_error( - "Failure while creating the ExecutionEngine."); - return new PyExecutionEngine(executionEngine); - }), - py::arg("module"), py::arg("opt_level") = 2, - py::arg("shared_libs") = py::list(), - py::arg("enable_object_dump") = true, - "Create a new ExecutionEngine instance for the given Module. The " - "module must contain only dialects that can be translated to LLVM. " - "Perform transformations and code generation at the optimization " - "level `opt_level` if specified, or otherwise at the default " - "level of two (-O2). Load a list of libraries specified in " - "`shared_libs`.") - .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR, - &PyExecutionEngine::getCapsule) + nb::class_(m, "ExecutionEngine") + .def( + "__init__", + [](PyExecutionEngine &self, MlirModule module, int optLevel, + const std::vector &sharedLibPaths, + bool enableObjectDump) { + llvm::SmallVector libPaths; + for (const std::string &path : sharedLibPaths) + libPaths.push_back({path.c_str(), path.length()}); + MlirExecutionEngine executionEngine = + mlirExecutionEngineCreate(module, optLevel, libPaths.size(), + libPaths.data(), enableObjectDump); + if (mlirExecutionEngineIsNull(executionEngine)) + throw std::runtime_error( + "Failure while creating the ExecutionEngine."); + new (&self) PyExecutionEngine(executionEngine); + }, + nb::arg("module"), nb::arg("opt_level") = 2, + nb::arg("shared_libs") = nb::list(), + nb::arg("enable_object_dump") = true, + "Create a new ExecutionEngine instance for the given Module. The " + "module must contain only dialects that can be translated to LLVM. " + "Perform transformations and code generation at the optimization " + "level `opt_level` if specified, or otherwise at the default " + "level of two (-O2). Load a list of libraries specified in " + "`shared_libs`.") + .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyExecutionEngine::getCapsule) .def("_testing_release", &PyExecutionEngine::release, "Releases (leaks) the backing ExecutionEngine (for testing purpose)") .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyExecutionEngine::createFromCapsule) @@ -107,21 +108,21 @@ PYBIND11_MODULE(_mlirExecutionEngine, m) { mlirStringRefCreate(func.c_str(), func.size())); return reinterpret_cast(res); }, - py::arg("func_name"), + nb::arg("func_name"), "Lookup function `func` in the ExecutionEngine.") .def( "raw_register_runtime", [](PyExecutionEngine &executionEngine, const std::string &name, - py::object callbackObj) { + nb::object callbackObj) { executionEngine.addReferencedObject(callbackObj); uintptr_t rawSym = - py::cast(py::getattr(callbackObj, "value")); + nb::cast(nb::getattr(callbackObj, "value")); mlirExecutionEngineRegisterSymbol( executionEngine.get(), mlirStringRefCreate(name.c_str(), name.size()), reinterpret_cast(rawSym)); }, - py::arg("name"), py::arg("callback"), + nb::arg("name"), nb::arg("callback"), "Register `callback` as the runtime symbol `name`.") .def( "dump_to_object_file", @@ -130,5 +131,5 @@ PYBIND11_MODULE(_mlirExecutionEngine, m) { executionEngine.get(), mlirStringRefCreate(fileName.c_str(), fileName.size())); }, - py::arg("file_name"), "Dump ExecutionEngine to an object file."); + nb::arg("file_name"), "Dump ExecutionEngine to an object file."); } diff --git a/mlir/lib/Bindings/Python/GPUPasses.cpp b/mlir/lib/Bindings/Python/GPUPasses.cpp index e276a3ce3a56a0..be474edbe9639a 100644 --- a/mlir/lib/Bindings/Python/GPUPasses.cpp +++ b/mlir/lib/Bindings/Python/GPUPasses.cpp @@ -8,14 +8,13 @@ #include "mlir-c/Dialect/GPU.h" -#include -#include +#include "mlir/Bindings/Python/Nanobind.h" // ----------------------------------------------------------------------------- // Module initialization. // ----------------------------------------------------------------------------- -PYBIND11_MODULE(_mlirGPUPasses, m) { +NB_MODULE(_mlirGPUPasses, m) { m.doc() = "MLIR GPU Dialect Passes"; // Register all GPU passes on load. diff --git a/mlir/lib/Bindings/Python/IRAffine.cpp b/mlir/lib/Bindings/Python/IRAffine.cpp index 2db690309fab8c..a2df824f59a534 100644 --- a/mlir/lib/Bindings/Python/IRAffine.cpp +++ b/mlir/lib/Bindings/Python/IRAffine.cpp @@ -6,10 +6,6 @@ // //===----------------------------------------------------------------------===// -#include -#include -#include - #include #include #include @@ -21,8 +17,9 @@ #include "NanobindUtils.h" #include "mlir-c/AffineExpr.h" #include "mlir-c/AffineMap.h" -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/IntegerSet.h" +#include "mlir/Bindings/Python/Nanobind.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. #include "mlir/Support/LLVM.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp b/mlir/lib/Bindings/Python/IRAttributes.cpp index 779af09509748e..08f7d4881e137b 100644 --- a/mlir/lib/Bindings/Python/IRAttributes.cpp +++ b/mlir/lib/Bindings/Python/IRAttributes.cpp @@ -6,13 +6,6 @@ // //===----------------------------------------------------------------------===// -#include -#include -#include -#include -#include -#include - #include #include #include @@ -24,6 +17,7 @@ #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/BuiltinTypes.h" #include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/raw_ostream.h" diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp index e1c56a3984314f..86afa956398ae5 100644 --- a/mlir/lib/Bindings/Python/IRCore.cpp +++ b/mlir/lib/Bindings/Python/IRCore.cpp @@ -6,26 +6,20 @@ // //===----------------------------------------------------------------------===// -#include -#include -#include -#include -#include -#include - #include #include #include "Globals.h" #include "IRModule.h" #include "NanobindUtils.h" -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/Debug.h" #include "mlir-c/Diagnostics.h" #include "mlir-c/IR.h" #include "mlir-c/Support.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Bindings/Python/IRInterfaces.cpp b/mlir/lib/Bindings/Python/IRInterfaces.cpp index c339a93e31857b..9e1fedaab52352 100644 --- a/mlir/lib/Bindings/Python/IRInterfaces.cpp +++ b/mlir/lib/Bindings/Python/IRInterfaces.cpp @@ -6,10 +6,6 @@ // //===----------------------------------------------------------------------===// -#include -#include -#include - #include #include #include @@ -21,6 +17,7 @@ #include "mlir-c/IR.h" #include "mlir-c/Interfaces.h" #include "mlir-c/Support.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Bindings/Python/IRModule.cpp b/mlir/lib/Bindings/Python/IRModule.cpp index 416a14218f125d..f7bf77e5a7e043 100644 --- a/mlir/lib/Bindings/Python/IRModule.cpp +++ b/mlir/lib/Bindings/Python/IRModule.cpp @@ -8,16 +8,14 @@ #include "IRModule.h" -#include -#include - #include #include #include "Globals.h" #include "NanobindUtils.h" -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/Support.h" +#include "mlir/Bindings/Python/Nanobind.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. namespace nb = nanobind; using namespace mlir; diff --git a/mlir/lib/Bindings/Python/IRModule.h b/mlir/lib/Bindings/Python/IRModule.h index a242ff26bbbf57..8fb32a225e65f1 100644 --- a/mlir/lib/Bindings/Python/IRModule.h +++ b/mlir/lib/Bindings/Python/IRModule.h @@ -10,9 +10,6 @@ #ifndef MLIR_BINDINGS_PYTHON_IRMODULES_H #define MLIR_BINDINGS_PYTHON_IRMODULES_H -#include -#include - #include #include #include @@ -26,6 +23,7 @@ #include "mlir-c/IntegerSet.h" #include "mlir-c/Transforms.h" #include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "llvm/ADT/DenseMap.h" namespace mlir { diff --git a/mlir/lib/Bindings/Python/IRTypes.cpp b/mlir/lib/Bindings/Python/IRTypes.cpp index 5cfa51142ac08f..0f2719c10a0275 100644 --- a/mlir/lib/Bindings/Python/IRTypes.cpp +++ b/mlir/lib/Bindings/Python/IRTypes.cpp @@ -11,12 +11,6 @@ #include "mlir/Bindings/Python/IRTypes.h" // clang-format on -#include -#include -#include -#include -#include - #include #include "IRModule.h" diff --git a/mlir/lib/Bindings/Python/LinalgPasses.cpp b/mlir/lib/Bindings/Python/LinalgPasses.cpp index 3f230207a42114..49f2ea94151a01 100644 --- a/mlir/lib/Bindings/Python/LinalgPasses.cpp +++ b/mlir/lib/Bindings/Python/LinalgPasses.cpp @@ -8,13 +8,13 @@ #include "mlir-c/Dialect/Linalg.h" -#include +#include "mlir/Bindings/Python/Nanobind.h" // ----------------------------------------------------------------------------- // Module initialization. // ----------------------------------------------------------------------------- -PYBIND11_MODULE(_mlirLinalgPasses, m) { +NB_MODULE(_mlirLinalgPasses, m) { m.doc() = "MLIR Linalg Dialect Passes"; // Register all Linalg passes on load. diff --git a/mlir/lib/Bindings/Python/MainModule.cpp b/mlir/lib/Bindings/Python/MainModule.cpp index e5e64a921a79ad..7c4064262012ef 100644 --- a/mlir/lib/Bindings/Python/MainModule.cpp +++ b/mlir/lib/Bindings/Python/MainModule.cpp @@ -6,14 +6,13 @@ // //===----------------------------------------------------------------------===// -#include -#include #include "Globals.h" #include "IRModule.h" #include "NanobindUtils.h" #include "Pass.h" #include "Rewrite.h" +#include "mlir/Bindings/Python/Nanobind.h" namespace nb = nanobind; using namespace mlir; diff --git a/mlir/lib/Bindings/Python/NanobindUtils.h b/mlir/lib/Bindings/Python/NanobindUtils.h index 3b0f7f698b22d4..ee193cf9f8ef86 100644 --- a/mlir/lib/Bindings/Python/NanobindUtils.h +++ b/mlir/lib/Bindings/Python/NanobindUtils.h @@ -10,9 +10,8 @@ #ifndef MLIR_BINDINGS_PYTHON_PYBINDUTILS_H #define MLIR_BINDINGS_PYTHON_PYBINDUTILS_H -#include - #include "mlir-c/Support.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/DataTypes.h" @@ -68,7 +67,7 @@ namespace detail { template struct MlirDefaultingCaster { - NB_TYPE_CASTER(DefaultingTy, const_name(DefaultingTy::kTypeDescription)); + NB_TYPE_CASTER(DefaultingTy, const_name(DefaultingTy::kTypeDescription)) bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) { if (src.is_none()) { diff --git a/mlir/lib/Bindings/Python/Pass.cpp b/mlir/lib/Bindings/Python/Pass.cpp index b5dce4fe4128a5..858c3bd5745fee 100644 --- a/mlir/lib/Bindings/Python/Pass.cpp +++ b/mlir/lib/Bindings/Python/Pass.cpp @@ -8,13 +8,10 @@ #include "Pass.h" -#include -#include -#include - #include "IRModule.h" -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/Pass.h" +#include "mlir/Bindings/Python/Nanobind.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. namespace nb = nanobind; using namespace nb::literals; diff --git a/mlir/lib/Bindings/Python/RegisterEverything.cpp b/mlir/lib/Bindings/Python/RegisterEverything.cpp index 6b2f6b0a6a3b86..3ba42bec5d80c3 100644 --- a/mlir/lib/Bindings/Python/RegisterEverything.cpp +++ b/mlir/lib/Bindings/Python/RegisterEverything.cpp @@ -7,9 +7,10 @@ //===----------------------------------------------------------------------===// #include "mlir-c/RegisterEverything.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -PYBIND11_MODULE(_mlirRegisterEverything, m) { +NB_MODULE(_mlirRegisterEverything, m) { m.doc() = "MLIR All Upstream Dialects, Translations and Passes Registration"; m.def("register_dialects", [](MlirDialectRegistry registry) { diff --git a/mlir/lib/Bindings/Python/Rewrite.cpp b/mlir/lib/Bindings/Python/Rewrite.cpp index b2c1de4be9a69c..0373f9c7affe9f 100644 --- a/mlir/lib/Bindings/Python/Rewrite.cpp +++ b/mlir/lib/Bindings/Python/Rewrite.cpp @@ -8,11 +8,10 @@ #include "Rewrite.h" -#include - #include "IRModule.h" -#include "mlir-c/Bindings/Python/Interop.h" #include "mlir-c/Rewrite.h" +#include "mlir/Bindings/Python/Nanobind.h" +#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind. #include "mlir/Config/mlir-config.h" namespace nb = nanobind; diff --git a/mlir/lib/Bindings/Python/SparseTensorPasses.cpp b/mlir/lib/Bindings/Python/SparseTensorPasses.cpp index 2a8e2b802df9c4..8242f0973a446c 100644 --- a/mlir/lib/Bindings/Python/SparseTensorPasses.cpp +++ b/mlir/lib/Bindings/Python/SparseTensorPasses.cpp @@ -8,13 +8,13 @@ #include "mlir-c/Dialect/SparseTensor.h" -#include +#include "mlir/Bindings/Python/Nanobind.h" // ----------------------------------------------------------------------------- // Module initialization. // ----------------------------------------------------------------------------- -PYBIND11_MODULE(_mlirSparseTensorPasses, m) { +NB_MODULE(_mlirSparseTensorPasses, m) { m.doc() = "MLIR SparseTensor Dialect Passes"; // Register all SparseTensor passes on load. diff --git a/mlir/lib/Bindings/Python/TransformInterpreter.cpp b/mlir/lib/Bindings/Python/TransformInterpreter.cpp index 0c8c0e0a965aa7..f9b0fed62778f4 100644 --- a/mlir/lib/Bindings/Python/TransformInterpreter.cpp +++ b/mlir/lib/Bindings/Python/TransformInterpreter.cpp @@ -10,16 +10,14 @@ // //===----------------------------------------------------------------------===// -#include -#include - #include "mlir-c/Dialect/Transform/Interpreter.h" #include "mlir-c/IR.h" #include "mlir-c/Support.h" #include "mlir/Bindings/Python/Diagnostics.h" -#include "mlir/Bindings/Python/PybindAdaptors.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" +#include "mlir/Bindings/Python/Nanobind.h" -namespace py = pybind11; +namespace nb = nanobind; namespace { struct PyMlirTransformOptions { @@ -36,10 +34,10 @@ struct PyMlirTransformOptions { }; } // namespace -static void populateTransformInterpreterSubmodule(py::module &m) { - py::class_(m, "TransformOptions", py::module_local()) - .def(py::init()) - .def_property( +static void populateTransformInterpreterSubmodule(nb::module_ &m) { + nb::class_(m, "TransformOptions") + .def(nb::init<>()) + .def_prop_rw( "expensive_checks", [](const PyMlirTransformOptions &self) { return mlirTransformOptionsGetExpensiveChecksEnabled(self.options); @@ -47,7 +45,7 @@ static void populateTransformInterpreterSubmodule(py::module &m) { [](PyMlirTransformOptions &self, bool value) { mlirTransformOptionsEnableExpensiveChecks(self.options, value); }) - .def_property( + .def_prop_rw( "enforce_single_top_level_transform_op", [](const PyMlirTransformOptions &self) { return mlirTransformOptionsGetEnforceSingleTopLevelTransformOp( @@ -68,7 +66,7 @@ static void populateTransformInterpreterSubmodule(py::module &m) { // Calling back into Python to invalidate everything under the payload // root. This is awkward, but we don't have access to PyMlirContext // object here otherwise. - py::object obj = py::cast(payloadRoot); + nb::object obj = nb::cast(payloadRoot); obj.attr("context").attr("_clear_live_operations_inside")(payloadRoot); MlirLogicalResult result = mlirTransformApplyNamedSequence( @@ -76,13 +74,14 @@ static void populateTransformInterpreterSubmodule(py::module &m) { if (mlirLogicalResultIsSuccess(result)) return; - throw py::value_error( - "Failed to apply named transform sequence.\nDiagnostic message " + - scope.takeMessage()); + throw nb::value_error( + ("Failed to apply named transform sequence.\nDiagnostic message " + + scope.takeMessage()) + .c_str()); }, - py::arg("payload_root"), py::arg("transform_root"), - py::arg("transform_module"), - py::arg("transform_options") = PyMlirTransformOptions()); + nb::arg("payload_root"), nb::arg("transform_root"), + nb::arg("transform_module"), + nb::arg("transform_options") = PyMlirTransformOptions()); m.def( "copy_symbols_and_merge_into", @@ -92,15 +91,16 @@ static void populateTransformInterpreterSubmodule(py::module &m) { MlirLogicalResult result = mlirMergeSymbolsIntoFromClone(target, other); if (mlirLogicalResultIsFailure(result)) { - throw py::value_error( - "Failed to merge symbols.\nDiagnostic message " + - scope.takeMessage()); + throw nb::value_error( + ("Failed to merge symbols.\nDiagnostic message " + + scope.takeMessage()) + .c_str()); } }, - py::arg("target"), py::arg("other")); + nb::arg("target"), nb::arg("other")); } -PYBIND11_MODULE(_mlirTransformInterpreter, m) { +NB_MODULE(_mlirTransformInterpreter, m) { m.doc() = "MLIR Transform dialect interpreter functionality."; populateTransformInterpreterSubmodule(m); } diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt index 6d6b983128b80f..fb115a5f43423a 100644 --- a/mlir/python/CMakeLists.txt +++ b/mlir/python/CMakeLists.txt @@ -476,9 +476,6 @@ declare_mlir_python_extension(MLIRPythonExtension.Core # Dialects MLIRCAPIFunc ) -if (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL) -set_target_properties(MLIRPythonExtension.Core PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-cast-qual;-Wno-zero-length-array;-Wno-extra-semi;-Wno-nested-anon-types;-Wno-pedantic") -endif() # This extension exposes an API to register all dialects, extensions, and passes # packaged in upstream MLIR and it is used for the upstream "mlir" Python @@ -490,6 +487,7 @@ endif() declare_mlir_python_extension(MLIRPythonExtension.RegisterEverything MODULE_NAME _mlirRegisterEverything ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES RegisterEverything.cpp PRIVATE_LINK_LIBS @@ -504,6 +502,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.Linalg.Pybind MODULE_NAME _mlirDialectsLinalg ADD_TO_PARENT MLIRPythonSources.Dialects.linalg ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectLinalg.cpp PRIVATE_LINK_LIBS @@ -517,6 +516,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.GPU.Pybind MODULE_NAME _mlirDialectsGPU ADD_TO_PARENT MLIRPythonSources.Dialects.gpu ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectGPU.cpp PRIVATE_LINK_LIBS @@ -530,6 +530,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.LLVM.Pybind MODULE_NAME _mlirDialectsLLVM ADD_TO_PARENT MLIRPythonSources.Dialects.llvm ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectLLVM.cpp PRIVATE_LINK_LIBS @@ -543,6 +544,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.Quant.Pybind MODULE_NAME _mlirDialectsQuant ADD_TO_PARENT MLIRPythonSources.Dialects.quant ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectQuant.cpp PRIVATE_LINK_LIBS @@ -556,6 +558,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.NVGPU.Pybind MODULE_NAME _mlirDialectsNVGPU ADD_TO_PARENT MLIRPythonSources.Dialects.nvgpu ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectNVGPU.cpp PRIVATE_LINK_LIBS @@ -569,6 +572,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.PDL.Pybind MODULE_NAME _mlirDialectsPDL ADD_TO_PARENT MLIRPythonSources.Dialects.pdl ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectPDL.cpp PRIVATE_LINK_LIBS @@ -582,6 +586,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.SparseTensor.Pybind MODULE_NAME _mlirDialectsSparseTensor ADD_TO_PARENT MLIRPythonSources.Dialects.sparse_tensor ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectSparseTensor.cpp PRIVATE_LINK_LIBS @@ -595,6 +600,7 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.Transform.Pybind MODULE_NAME _mlirDialectsTransform ADD_TO_PARENT MLIRPythonSources.Dialects.transform ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES DialectTransform.cpp PRIVATE_LINK_LIBS @@ -608,6 +614,7 @@ declare_mlir_python_extension(MLIRPythonExtension.AsyncDialectPasses MODULE_NAME _mlirAsyncPasses ADD_TO_PARENT MLIRPythonSources.Dialects.async ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES AsyncPasses.cpp PRIVATE_LINK_LIBS @@ -621,6 +628,7 @@ if(MLIR_ENABLE_EXECUTION_ENGINE) MODULE_NAME _mlirExecutionEngine ADD_TO_PARENT MLIRPythonSources.ExecutionEngine ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES ExecutionEngineModule.cpp PRIVATE_LINK_LIBS @@ -634,6 +642,7 @@ declare_mlir_python_extension(MLIRPythonExtension.GPUDialectPasses MODULE_NAME _mlirGPUPasses ADD_TO_PARENT MLIRPythonSources.Dialects.gpu ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES GPUPasses.cpp PRIVATE_LINK_LIBS @@ -646,6 +655,7 @@ declare_mlir_python_extension(MLIRPythonExtension.LinalgPasses MODULE_NAME _mlirLinalgPasses ADD_TO_PARENT MLIRPythonSources.Dialects.linalg ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES LinalgPasses.cpp PRIVATE_LINK_LIBS @@ -658,6 +668,7 @@ declare_mlir_python_extension(MLIRPythonExtension.SparseTensorDialectPasses MODULE_NAME _mlirSparseTensorPasses ADD_TO_PARENT MLIRPythonSources.Dialects.sparse_tensor ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES SparseTensorPasses.cpp PRIVATE_LINK_LIBS @@ -670,6 +681,7 @@ declare_mlir_python_extension(MLIRPythonExtension.TransformInterpreter MODULE_NAME _mlirTransformInterpreter ADD_TO_PARENT MLIRPythonSources.Dialects.transform ROOT_DIR "${PYTHON_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind SOURCES TransformInterpreter.cpp PRIVATE_LINK_LIBS @@ -735,9 +747,6 @@ if(MLIR_INCLUDE_TESTS) EMBED_CAPI_LINK_LIBS MLIRCAPIPythonTestDialect ) - if (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL) - set_target_properties(MLIRPythonTestSources.PythonTestExtensionNanobind PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-cast-qual;-Wno-zero-length-array;-Wno-extra-semi;-Wno-nested-anon-types;-Wno-pedantic") - endif() endif() ################################################################################ @@ -794,3 +803,4 @@ add_mlir_python_modules(MLIRPythonModules COMMON_CAPI_LINK_LIBS MLIRPythonCAPI ) + diff --git a/mlir/test/python/dialects/sparse_tensor/dialect.py b/mlir/test/python/dialects/sparse_tensor/dialect.py index 656979f3d9a1df..c72a69830a1e8e 100644 --- a/mlir/test/python/dialects/sparse_tensor/dialect.py +++ b/mlir/test/python/dialects/sparse_tensor/dialect.py @@ -90,7 +90,7 @@ def testEncodingAttrStructure(): # CHECK: lvl_types: [65536, 65536, 4406638542848] print(f"lvl_types: {casted.lvl_types}") - # CHECK: lvl_formats_enum: [, , ] + # CHECK: lvl_formats_enum: [{{65536|LevelFormat.dense}}, {{65536|LevelFormat.dense}}, {{2097152|LevelFormat.n_out_of_m}}] print(f"lvl_formats_enum: {casted.lvl_formats_enum}") # CHECK: structured_n: 2 print(f"structured_n: {casted.structured_n}") diff --git a/mlir/test/python/lib/PythonTestModuleNanobind.cpp b/mlir/test/python/lib/PythonTestModuleNanobind.cpp index 7c504d04be0d13..99c81eae97a0cf 100644 --- a/mlir/test/python/lib/PythonTestModuleNanobind.cpp +++ b/mlir/test/python/lib/PythonTestModuleNanobind.cpp @@ -8,13 +8,11 @@ // This is the nanobind edition of the PythonTest dialect module. //===----------------------------------------------------------------------===// -#include -#include - #include "PythonTestCAPI.h" #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/BuiltinTypes.h" #include "mlir-c/IR.h" +#include "mlir/Bindings/Python/Nanobind.h" #include "mlir/Bindings/Python/NanobindAdaptors.h" namespace nb = nanobind; diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index d2ac43ef5bcff2..f1192d069fa5f5 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -1131,7 +1131,8 @@ cc_binary( deps = [ ":CAPIIR", ":CAPILinalg", - ":MLIRBindingsPythonHeadersAndDeps", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", ], ) @@ -1145,8 +1146,8 @@ cc_binary( deps = [ ":CAPIIR", ":CAPILLVM", - ":MLIRBindingsPythonHeadersAndDeps", - "@pybind11", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", ], ) @@ -1160,8 +1161,8 @@ cc_binary( deps = [ ":CAPIIR", ":CAPIQuant", - ":MLIRBindingsPythonHeadersAndDeps", - "@pybind11", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", ], ) @@ -1175,8 +1176,8 @@ cc_binary( deps = [ ":CAPIIR", ":CAPISparseTensor", - ":MLIRBindingsPythonHeadersAndDeps", - "@pybind11", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", ], ) @@ -1190,8 +1191,8 @@ cc_binary( linkstatic = 0, deps = [ ":CAPIExecutionEngine", - ":MLIRBindingsPythonHeadersAndDeps", - "@pybind11", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", "@rules_python//python/cc:current_py_cc_headers", ], ) @@ -1206,8 +1207,8 @@ cc_binary( linkstatic = 0, deps = [ ":CAPILinalg", - ":MLIRBindingsPythonHeadersAndDeps", - "@pybind11", + ":MLIRBindingsPythonNanobindHeadersAndDeps", + "@nanobind", "@rules_python//python/cc:current_py_cc_headers", ], ) From cbf931e16f6d1ebe4c8a2f32315f21615a934f32 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sat, 21 Dec 2024 08:06:29 +0300 Subject: [PATCH 04/10] [TableGen][GlobalISel] Add GINodeEquiv for sdivrem/udivrem (#120819) These nodes are not currently used in DAG patterns. Their GlobalISel equivalents are primarily useful for testing TableGen backend, as they produce two results. (There doesn't seem to be other such nodes.) --- llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td | 2 ++ llvm/include/llvm/Target/TargetSelectionDAG.td | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 2148f5be4c41aa..c8c0eeb57099a2 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -70,6 +70,8 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index 2c58eedce1de0b..bee0a4298c786f 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -128,8 +128,8 @@ def SDTIntShiftDOp: SDTypeProfile<1, 3, [ // fshl, fshr def SDTIntSatNoShOp : SDTypeProfile<1, 2, [ // ssat with no shift SDTCisSameAs<0, 1>, SDTCisInt<2> ]>; -def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0> +def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // smullohi, umullohi, sdivrem, udivrem + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisInt<0> ]>; def SDTIntScaledBinOp : SDTypeProfile<1, 3, [ // smulfix, sdivfix, etc SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3> From 665d79f2e967a5eee6fff93685e45f50cf24cab2 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Fri, 20 Dec 2024 22:13:59 -0800 Subject: [PATCH 05/10] [AArch64][GlobalISel] Implement G_ICMP support for oversize pointer vectors. --- .../AArch64/GISel/AArch64LegalizerInfo.cpp | 7 +- .../AArch64/GlobalISel/legalize-cmp.mir | 65 +++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index f83ad7aa7460eb..155d98f0865f7a 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -563,13 +563,16 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) [=](const LegalityQuery &Query) { return Query.Types[1] == v2s16; }, 1, s32) .minScalarOrEltIf( - [=](const LegalityQuery &Query) { return Query.Types[1] == v2p0; }, 0, - s64) + [=](const LegalityQuery &Query) { + return Query.Types[1].isPointerVector(); + }, + 0, s64) .moreElementsToNextPow2(1) .clampNumElements(1, v8s8, v16s8) .clampNumElements(1, v4s16, v8s16) .clampNumElements(1, v2s32, v4s32) .clampNumElements(1, v2s64, v2s64) + .clampNumElements(1, v2p0, v2p0) .customIf(isVector(0)); getActionDefinitionsBuilder(G_FCMP) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir index d96f6fbc12c7ca..40fd92b9504e00 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir @@ -541,3 +541,68 @@ body: | %zext:_(s32) = G_ZEXT %2(s8) $w0 = COPY %zext(s32) RET_ReallyLR +... +--- +name: test_4xs64_ne +tracksRegLiveness: true +body: | + bb.1: + liveins: + ; CHECK-LABEL: name: test_4xs64_ne + ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(eq), [[DEF]](<2 x s64>), [[DEF]] + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64) + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]] + ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(eq), [[DEF]](<2 x s64>), [[DEF]] + ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64) + ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]] + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[XOR]](<2 x s64>) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[XOR1]](<2 x s64>) + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[TRUNC]](<2 x s32>), [[TRUNC1]](<2 x s32>) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[CONCAT_VECTORS]](<4 x s32>), [[C1]](s64) + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK-NEXT: %zext:_(s32) = G_AND [[EVEC]], [[C2]] + ; CHECK-NEXT: $w0 = COPY %zext(s32) + ; CHECK-NEXT: RET_ReallyLR + %vec:_(<4 x s64>) = G_IMPLICIT_DEF + %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %vec(<4 x s64>), %vec + %1:_(s64) = G_CONSTANT i64 1 + %elt:_(s1) = G_EXTRACT_VECTOR_ELT %cmp(<4 x s1>), %1 + %zext:_(s32) = G_ZEXT %elt(s1) + $w0 = COPY %zext(s32) + RET_ReallyLR +... +--- +name: test_4xp0_ne +tracksRegLiveness: true +body: | + bb.1: + liveins: + ; CHECK-LABEL: name: test_4xp0_ne + ; CHECK: [[DEF:%[0-9]+]]:_(<2 x p0>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(eq), [[DEF]](<2 x p0>), [[DEF]] + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64) + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]] + ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(eq), [[DEF]](<2 x p0>), [[DEF]] + ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64) + ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]] + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[XOR]](<2 x s64>) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[XOR1]](<2 x s64>) + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[TRUNC]](<2 x s32>), [[TRUNC1]](<2 x s32>) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[CONCAT_VECTORS]](<4 x s32>), [[C1]](s64) + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK-NEXT: %zext:_(s32) = G_AND [[EVEC]], [[C2]] + ; CHECK-NEXT: $w0 = COPY %zext(s32) + ; CHECK-NEXT: RET_ReallyLR + %vec:_(<4 x p0>) = G_IMPLICIT_DEF + %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %vec(<4 x p0>), %vec + %1:_(s64) = G_CONSTANT i64 1 + %elt:_(s1) = G_EXTRACT_VECTOR_ELT %cmp(<4 x s1>), %1 + %zext:_(s32) = G_ZEXT %elt(s1) + $w0 = COPY %zext(s32) + RET_ReallyLR +... From 7a38445ee2ac89fe240479d052373df23561ab57 Mon Sep 17 00:00:00 2001 From: vporpo Date: Fri, 20 Dec 2024 23:10:24 -0800 Subject: [PATCH 06/10] [SandboxVec][DAG] Register move instr callback (#120146) This patch implements the move instruction notifier for the DAG. Whenever an instruction moves the notifier will maintain the DAG. --- .../SandboxVectorizer/DependencyGraph.h | 18 ++++++++ .../SandboxVectorizer/DependencyGraph.cpp | 46 +++++++++++++++++++ .../SandboxVectorizer/DependencyGraphTest.cpp | 35 +++++++++++++- 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h index b1cad2421bc0d2..f423e1ee456cd1 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h @@ -220,6 +220,14 @@ class MemDGNode final : public DGNode { void setNextNode(MemDGNode *N) { NextMemN = N; } void setPrevNode(MemDGNode *N) { PrevMemN = N; } friend class DependencyGraph; // For setNextNode(), setPrevNode(). + void detachFromChain() { + if (PrevMemN != nullptr) + PrevMemN->NextMemN = NextMemN; + if (NextMemN != nullptr) + NextMemN->PrevMemN = PrevMemN; + PrevMemN = nullptr; + NextMemN = nullptr; + } public: MemDGNode(Instruction *I) : DGNode(I, DGNodeID::MemDGNode) { @@ -293,6 +301,7 @@ class DependencyGraph { Context *Ctx = nullptr; std::optional CreateInstrCB; std::optional EraseInstrCB; + std::optional MoveInstrCB; std::unique_ptr BatchAA; @@ -343,6 +352,9 @@ class DependencyGraph { /// Called by the callbacks when instruction \p I is about to get /// deleted. void notifyEraseInstr(Instruction *I); + /// Called by the callbacks when instruction \p I is about to be moved to + /// \p To. + void notifyMoveInstr(Instruction *I, const BBIterator &To); public: /// This constructor also registers callbacks. @@ -352,12 +364,18 @@ class DependencyGraph { [this](Instruction *I) { notifyCreateInstr(I); }); EraseInstrCB = Ctx.registerEraseInstrCallback( [this](Instruction *I) { notifyEraseInstr(I); }); + MoveInstrCB = Ctx.registerMoveInstrCallback( + [this](Instruction *I, const BBIterator &To) { + notifyMoveInstr(I, To); + }); } ~DependencyGraph() { if (CreateInstrCB) Ctx->unregisterCreateInstrCallback(*CreateInstrCB); if (EraseInstrCB) Ctx->unregisterEraseInstrCallback(*EraseInstrCB); + if (MoveInstrCB) + Ctx->unregisterMoveInstrCallback(*MoveInstrCB); } DGNode *getNode(Instruction *I) const { diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp index 25f2665d450d13..ba62c45a4e704e 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp @@ -370,6 +370,52 @@ void DependencyGraph::notifyCreateInstr(Instruction *I) { } } +void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) { + // Early return if `I` doesn't actually move. + BasicBlock *BB = To.getNodeParent(); + if (To != BB->end() && &*To == I->getNextNode()) + return; + + // Maintain the DAGInterval. + DAGInterval.notifyMoveInstr(I, To); + + // TODO: Perhaps check if this is legal by checking the dependencies? + + // Update the MemDGNode chain to reflect the instr movement if necessary. + DGNode *N = getNodeOrNull(I); + if (N == nullptr) + return; + MemDGNode *MemN = dyn_cast(N); + if (MemN == nullptr) + return; + // First detach it from the existing chain. + MemN->detachFromChain(); + // Now insert it back into the chain at the new location. + if (To != BB->end()) { + DGNode *ToN = getNodeOrNull(&*To); + if (ToN != nullptr) { + MemDGNode *PrevMemN = getMemDGNodeBefore(ToN, /*IncludingN=*/false); + MemDGNode *NextMemN = getMemDGNodeAfter(ToN, /*IncludingN=*/true); + MemN->PrevMemN = PrevMemN; + if (PrevMemN != nullptr) + PrevMemN->NextMemN = MemN; + MemN->NextMemN = NextMemN; + if (NextMemN != nullptr) + NextMemN->PrevMemN = MemN; + } + } else { + // MemN becomes the last instruction in the BB. + auto *TermN = getNodeOrNull(BB->getTerminator()); + if (TermN != nullptr) { + MemDGNode *PrevMemN = getMemDGNodeBefore(TermN, /*IncludingN=*/false); + PrevMemN->NextMemN = MemN; + MemN->PrevMemN = PrevMemN; + } else { + // The terminator is outside the DAG interval so do nothing. + } + } +} + void DependencyGraph::notifyEraseInstr(Instruction *I) { // Update the MemDGNode chain if this is a memory node. if (auto *MemN = dyn_cast_or_null(getNodeOrNull(I))) { diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp index 8c73ee1def8ae1..3fa4de501f3f5d 100644 --- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp @@ -801,7 +801,7 @@ define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) { TEST_F(DependencyGraphTest, CreateInstrCallback) { parseIR(C, R"IR( -define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %arg) { +define void @foo(ptr %ptr, ptr noalias %ptr2, i8 %v1, i8 %v2, i8 %v3, i8 %arg) { store i8 %v1, ptr %ptr store i8 %v2, ptr %ptr store i8 %v3, ptr %ptr @@ -893,3 +893,36 @@ define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %arg) { // TODO: Check the dependencies to/from NewSN after they land. } + +TEST_F(DependencyGraphTest, MoveInstrCallback) { + parseIR(C, R"IR( +define void @foo(ptr %ptr, ptr %ptr2, i8 %v1, i8 %v2, i8 %v3, i8 %arg) { + %ld0 = load i8, ptr %ptr2 + store i8 %v1, ptr %ptr + store i8 %v2, ptr %ptr + store i8 %v3, ptr %ptr + ret void +} +)IR"); + llvm::Function *LLVMF = &*M->getFunction("foo"); + sandboxir::Context Ctx(C); + auto *F = Ctx.createFunction(LLVMF); + auto *BB = &*F->begin(); + auto It = BB->begin(); + auto *Ld = cast(&*It++); + auto *S1 = cast(&*It++); + auto *S2 = cast(&*It++); + auto *S3 = cast(&*It++); + + sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx); + DAG.extend({Ld, S3}); + auto *LdN = cast(DAG.getNode(Ld)); + auto *S1N = cast(DAG.getNode(S1)); + auto *S2N = cast(DAG.getNode(S2)); + EXPECT_EQ(S1N->getPrevNode(), LdN); + S1->moveBefore(Ld); + EXPECT_EQ(S1N->getPrevNode(), nullptr); + EXPECT_EQ(S1N->getNextNode(), LdN); + EXPECT_EQ(LdN->getPrevNode(), S1N); + EXPECT_EQ(LdN->getNextNode(), S2N); +} From f06756f50e1f70664adc25a41ccabf5b018a504a Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sat, 21 Dec 2024 20:19:56 +1300 Subject: [PATCH 07/10] Store sysreg names in-line with their descriptors. (#119157) This wastes some disk space, because we have to size the arrays for the maximum possible length. However, it eliminates dynamic relocations from the SysRegsList arrays. --- llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h | 4 ++-- llvm/lib/Target/ARM/Utils/ARMBaseInfo.h | 2 +- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 8f34cf054fe286..e0ccba4d6a59e8 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -700,8 +700,8 @@ AArch64StringToVectorLayout(StringRef LayoutStr) { namespace AArch64SysReg { struct SysReg { - const char *Name; - const char *AltName; + const char Name[32]; + const char AltName[32]; unsigned Encoding; bool Readable; bool Writeable; diff --git a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h index 56a925f09ea7ae..5562572c5abf48 100644 --- a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h @@ -189,7 +189,7 @@ inline static unsigned ARMCondCodeFromString(StringRef CC) { // System Registers namespace ARMSysReg { struct MClassSysReg { - const char *Name; + const char Name[32]; uint16_t M1Encoding12; uint16_t M2M3Encoding8; uint16_t Encoding; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 056b6da34ac708..370350719b2308 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -452,9 +452,9 @@ int getLoadFPImm(APFloat FPImm); namespace RISCVSysReg { struct SysReg { - const char *Name; - const char *AltName; - const char *DeprecatedName; + const char Name[32]; + const char AltName[32]; + const char DeprecatedName[32]; unsigned Encoding; // FIXME: add these additional fields when needed. // Privilege Access: Read, Write, Read-Only. From e138f7831e62054d3971f716273fbe174176deca Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 20 Dec 2024 23:29:58 -0800 Subject: [PATCH 08/10] [RISCV] Remove unnecessary 'let BaseInstr' from Xsfvcp pseudoinstructions. NFC These are identical to the RISCVVPseudo base class. --- llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td | 6 ------ 1 file changed, 6 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td index 1ad3e1b681466b..20adda91f6bde1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td @@ -238,7 +238,6 @@ class VPseudoVC_X : let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; - let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_XV : @@ -251,7 +250,6 @@ class VPseudoVC_XV : let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; - let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_XVV(PseudoToVInst.VInst); } class VPseudoVC_V_X : @@ -278,7 +275,6 @@ class VPseudoVC_V_X : let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; - let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_V_XV(PseudoToVInst.VInst); } class VPseudoVC_V_XVV(PseudoToVInst.VInst); } multiclass VPseudoVC_X Date: Sat, 21 Dec 2024 09:47:07 +0000 Subject: [PATCH 09/10] [RISCV][NFCI] Rationalize Immediate Definitions (#120718) --- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 6 +-- .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 10 ++--- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 18 ++++---- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 42 ++++++++----------- llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 5 +-- llvm/lib/Target/RISCV/RISCVInstrInfoV.td | 8 +--- llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td | 42 ++++++------------- 7 files changed, 48 insertions(+), 83 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 370350719b2308..b9f4db065f2159 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -316,6 +316,9 @@ enum OperandType : unsigned { OPERAND_UIMM11, OPERAND_UIMM12, OPERAND_UIMM16, + OPERAND_UIMM20, + OPERAND_UIMMLOG2XLEN, + OPERAND_UIMMLOG2XLEN_NONZERO, OPERAND_UIMM32, OPERAND_UIMM48, OPERAND_UIMM64, @@ -327,9 +330,6 @@ enum OperandType : unsigned { OPERAND_SIMM10_LSB0000_NONZERO, OPERAND_SIMM12, OPERAND_SIMM12_LSB00000, - OPERAND_UIMM20, - OPERAND_UIMMLOG2XLEN, - OPERAND_UIMMLOG2XLEN_NONZERO, OPERAND_CLUI_IMM, OPERAND_VTYPEI10, OPERAND_VTYPEI11, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index a28bf1186589d9..06d9cce48692a5 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -80,11 +80,11 @@ class RISCVMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; - unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, + uint64_t getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; - unsigned getImmOpValue(const MCInst &MI, unsigned OpNo, + uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; @@ -385,14 +385,14 @@ RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, return 0; } -unsigned +uint64_t RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(OpNo); if (MO.isImm()) { - unsigned Res = MO.getImm(); + uint64_t Res = MO.getImm(); assert((Res & 1) == 0 && "LSB is non-zero"); return Res >> 1; } @@ -400,7 +400,7 @@ RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, return getImmOpValue(MI, OpNo, Fixups, STI); } -unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, +uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 0af8161a307abd..ee720ceb22b00f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2466,6 +2466,10 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, #define CASE_OPERAND_UIMM(NUM) \ case RISCVOp::OPERAND_UIMM##NUM: \ Ok = isUInt(Imm); \ + break; +#define CASE_OPERAND_SIMM(NUM) \ + case RISCVOp::OPERAND_SIMM##NUM: \ + Ok = isInt(Imm); \ break; CASE_OPERAND_UIMM(1) CASE_OPERAND_UIMM(2) @@ -2511,15 +2515,14 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_ZERO: Ok = Imm == 0; break; - case RISCVOp::OPERAND_SIMM5: - Ok = isInt<5>(Imm); - break; + // clang-format off + CASE_OPERAND_SIMM(5) + CASE_OPERAND_SIMM(6) + CASE_OPERAND_SIMM(12) + // clang-format on case RISCVOp::OPERAND_SIMM5_PLUS1: Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16; break; - case RISCVOp::OPERAND_SIMM6: - Ok = isInt<6>(Imm); - break; case RISCVOp::OPERAND_SIMM6_NONZERO: Ok = Imm != 0 && isInt<6>(Imm); break; @@ -2529,9 +2532,6 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_VTYPEI11: Ok = isUInt<11>(Imm); break; - case RISCVOp::OPERAND_SIMM12: - Ok = isInt<12>(Imm); - break; case RISCVOp::OPERAND_SIMM12_LSB00000: Ok = isShiftedInt<7, 5>(Imm); break; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index ac9805ded9d307..6651aedb0d8d88 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -159,8 +159,15 @@ class RISCVOp : Operand { class RISCVUImmOp : RISCVOp { let ParserMatchClass = UImmAsmOperand; + let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">"; let OperandType = "OPERAND_UIMM" # bitsNum; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isUInt<}]# bitsNum #[{>(Imm); + }]; } class RISCVUImmLeafOp : @@ -171,6 +178,12 @@ class RISCVSImmOp : RISCVOp { let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">"; let OperandType = "OPERAND_SIMM" # bitsNum; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isInt<}] # bitsNum # [{>(Imm); + }]; } class RISCVSImmLeafOp : @@ -221,16 +234,9 @@ def InsnDirectiveOpcode : AsmOperandClass { } def uimm1 : RISCVUImmLeafOp<1>; -def uimm2 : RISCVUImmLeafOp<2> { - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isUInt<2>(Imm); - }]; -} +def uimm2 : RISCVUImmLeafOp<2>; def uimm3 : RISCVUImmOp<3>; -def uimm4 : RISCVUImmOp<4>; +def uimm4 : RISCVUImmLeafOp<4>; def uimm5 : RISCVUImmLeafOp<5>; def uimm6 : RISCVUImmLeafOp<6>; def uimm7_opcode : RISCVUImmOp<7> { @@ -271,13 +277,7 @@ def simm13_lsb0 : Operand { let OperandType = "OPERAND_PCREL"; } -class UImm20Operand : RISCVOp { - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<20>"; - let OperandType = "OPERAND_UIMM20"; -} - -class UImm20OperandMaybeSym : UImm20Operand { +class UImm20OperandMaybeSym : RISCVUImmOp<20> { let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -293,15 +293,7 @@ def uimm20_auipc : UImm20OperandMaybeSym { let ParserMatchClass = UImmAsmOperand<20, "AUIPC">; } -def uimm20 : UImm20Operand { - let ParserMatchClass = UImmAsmOperand<20>; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isUInt<20>(Imm); - }]; -} +def uimm20 : RISCVUImmOp<20>; def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> { let ParserMethod = "parseJALOffset"; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index e5a5f60f9fec10..ce994206cd785b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -151,7 +151,6 @@ def simm9_lsb0 : Operand, if (MCOp.evaluateAsConstantImm(Imm)) return isShiftedInt<8, 1>(Imm); return MCOp.isBareSymbolRef(); - }]; let OperandType = "OPERAND_PCREL"; } @@ -227,10 +226,8 @@ def InsnCDirectiveOpcode : AsmOperandClass { let PredicateMethod = "isImm"; } -def uimm2_opcode : RISCVOp { +def uimm2_opcode : RISCVUImmOp<2> { let ParserMatchClass = InsnCDirectiveOpcode; - let DecoderMethod = "decodeUImmOperand<2>"; - let OperandType = "OPERAND_UIMM2"; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td index 6506b6746b1517..24a881dc6810f8 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -66,15 +66,9 @@ def simm5 : RISCVSImmLeafOp<5> { }]; } -def SImm5Plus1AsmOperand : AsmOperandClass { - let Name = "SImm5Plus1"; - let RenderMethod = "addImmOperands"; - let DiagnosticType = "InvalidSImm5Plus1"; -} - def simm5_plus1 : RISCVOp, ImmLeaf(Imm) && Imm != -16) || Imm == 16;}]> { - let ParserMatchClass = SImm5Plus1AsmOperand; + let ParserMatchClass = SImmAsmOperand<5, "Plus1">; let OperandType = "OPERAND_SIMM5_PLUS1"; let MCOperandPredicate = [{ int64_t Imm; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td index 91ff804ba105ac..a43cbadf6f3080 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td @@ -25,24 +25,6 @@ class QKStackInst funct2, dag outs, dag ins, // Operand definitions. //===----------------------------------------------------------------------===// -def uimm4_with_predicate : RISCVUImmLeafOp<4> { - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isUInt<4>(Imm); - }]; -} - -def uimm5_with_predicate : RISCVUImmLeafOp<5> { - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isUInt<5>(Imm); - }]; -} - // A 5-bit unsigned immediate where the least significant bit is zero. def uimm5_lsb0 : RISCVOp, ImmLeaf(Imm);}]> { @@ -80,7 +62,7 @@ let Predicates = [HasVendorXwchc], DecoderNamespace = "Xwchc" in { let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in def QK_C_LBU : RVInst16CL<0b001, 0b00, (outs GPRC:$rd), - (ins GPRCMem:$rs1, uimm5_with_predicate:$imm), + (ins GPRCMem:$rs1, uimm5:$imm), "qk.c.lbu", "$rd, ${imm}(${rs1})">, Sched<[WriteLDB, ReadMemBase]> { bits<5> imm; @@ -91,7 +73,7 @@ def QK_C_LBU : RVInst16CL<0b001, 0b00, (outs GPRC:$rd), let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in def QK_C_SB : RVInst16CS<0b101, 0b00, (outs), (ins GPRC:$rs2, GPRCMem:$rs1, - uimm5_with_predicate:$imm), + uimm5:$imm), "qk.c.sb", "$rs2, ${imm}(${rs1})">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]> { bits<5> imm; @@ -121,7 +103,7 @@ def QK_C_SH : RVInst16CS<0b101, 0b10, (outs), let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in def QK_C_LBUSP : QKStackInst<0b00, (outs GPRC:$rd_rs2), - (ins SPMem:$rs1, uimm4_with_predicate:$imm), + (ins SPMem:$rs1, uimm4:$imm), "qk.c.lbusp", "$rd_rs2, ${imm}(${rs1})">, Sched<[WriteLDB, ReadMemBase]> { bits<4> imm; @@ -130,7 +112,7 @@ def QK_C_LBUSP : QKStackInst<0b00, (outs GPRC:$rd_rs2), let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in def QK_C_SBSP : QKStackInst<0b10, (outs), (ins GPRC:$rd_rs2, SPMem:$rs1, - uimm4_with_predicate:$imm), + uimm4:$imm), "qk.c.sbsp", "$rd_rs2, ${imm}(${rs1})">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]> { bits<4> imm; @@ -180,18 +162,18 @@ def : InstAlias<"qk.c.shsp $rs2, (${rs1})", (QK_C_SHSP GPRC:$rs2, SPMem:$rs1, 0) //===----------------------------------------------------------------------===// let Predicates = [HasVendorXwchc] in { -def : CompressPat<(LBU GPRC:$rd, GPRCMem:$rs1, uimm5_with_predicate:$imm), - (QK_C_LBU GPRC:$rd, GPRCMem:$rs1, uimm5_with_predicate:$imm)>; -def : CompressPat<(SB GPRC:$rs2, GPRCMem:$rs1, uimm5_with_predicate:$imm), - (QK_C_SB GPRC:$rs2, GPRCMem:$rs1, uimm5_with_predicate:$imm)>; +def : CompressPat<(LBU GPRC:$rd, GPRCMem:$rs1, uimm5:$imm), + (QK_C_LBU GPRC:$rd, GPRCMem:$rs1, uimm5:$imm)>; +def : CompressPat<(SB GPRC:$rs2, GPRCMem:$rs1, uimm5:$imm), + (QK_C_SB GPRC:$rs2, GPRCMem:$rs1, uimm5:$imm)>; def : CompressPat<(LHU GPRC:$rd, GPRCMem:$rs1, uimm6_lsb0:$imm), (QK_C_LHU GPRC:$rd, GPRCMem:$rs1, uimm6_lsb0:$imm)>; def : CompressPat<(SH GPRC:$rs2, GPRCMem:$rs1, uimm6_lsb0:$imm), (QK_C_SH GPRC:$rs2, GPRCMem:$rs1, uimm6_lsb0:$imm)>; -def : CompressPat<(LBU GPRC:$rd, SPMem:$rs1, uimm4_with_predicate:$imm), - (QK_C_LBUSP GPRC:$rd, SPMem:$rs1, uimm4_with_predicate:$imm)>; -def : CompressPat<(SB GPRC:$rs2, SPMem:$rs1, uimm4_with_predicate:$imm), - (QK_C_SBSP GPRC:$rs2, SPMem:$rs1, uimm4_with_predicate:$imm)>; +def : CompressPat<(LBU GPRC:$rd, SPMem:$rs1, uimm4:$imm), + (QK_C_LBUSP GPRC:$rd, SPMem:$rs1, uimm4:$imm)>; +def : CompressPat<(SB GPRC:$rs2, SPMem:$rs1, uimm4:$imm), + (QK_C_SBSP GPRC:$rs2, SPMem:$rs1, uimm4:$imm)>; def : CompressPat<(LHU GPRC:$rd, SPMem:$rs1, uimm5_lsb0:$imm), (QK_C_LHUSP GPRC:$rd, SPMem:$rs1, uimm5_lsb0:$imm)>; def : CompressPat<(SH GPRC:$rs2, SPMem:$rs1, uimm5_lsb0:$imm), From c361fd5a7a8d646e11ee51acf4ba6de5f5e1297c Mon Sep 17 00:00:00 2001 From: Sam Elliott Date: Sat, 21 Dec 2024 09:48:31 +0000 Subject: [PATCH 10/10] [RISCV] Fix More RV32 Signed Immediates (#120658) --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 8 ++-- llvm/test/MC/RISCV/rv32c-only-valid.s | 28 ++++++++++++ llvm/test/MC/RISCV/rv32i-only-valid.s | 45 ++++++++++++++++++- llvm/test/MC/RISCV/rv32zcibop-valid-rv32.s | 18 ++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 llvm/test/MC/RISCV/rv32zcibop-valid-rv32.s diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 5b9946e5132e40..9dcf2e973e6c58 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -530,7 +530,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { if (!IsConstantImm) IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); else - IsValid = isShiftedInt(Imm); + IsValid = isShiftedInt(fixImmediateForRV32(Imm, isRV64Imm())); return IsValid && VK == RISCVMCExpr::VK_RISCV_None; } @@ -943,7 +943,8 @@ struct RISCVOperand final : public MCParsedAsmOperand { RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; int64_t Imm; bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); - return IsConstantImm && isShiftedInt<7, 5>(Imm) && + return IsConstantImm && + isShiftedInt<7, 5>(fixImmediateForRV32(Imm, isRV64Imm())) && VK == RISCVMCExpr::VK_RISCV_None; } @@ -955,7 +956,8 @@ struct RISCVOperand final : public MCParsedAsmOperand { int64_t Imm; RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); - return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && + return IsConstantImm && (Imm != 0) && + isShiftedInt<6, 4>(fixImmediateForRV32(Imm, isRV64Imm())) && VK == RISCVMCExpr::VK_RISCV_None; } diff --git a/llvm/test/MC/RISCV/rv32c-only-valid.s b/llvm/test/MC/RISCV/rv32c-only-valid.s index 70f358ef24fce1..3321aff115c4d0 100644 --- a/llvm/test/MC/RISCV/rv32c-only-valid.s +++ b/llvm/test/MC/RISCV/rv32c-only-valid.s @@ -26,3 +26,31 @@ c.jal 2046 # CHECK-ASM: c.addi a1, -1 # CHECK-ASM: encoding: [0xfd,0x15] c.addi a1, 0xffffffff + +# CHECK-OBJ: c.addi16sp sp, -352 +# CHECK-ASM: c.addi16sp sp, -352 +# CHECK-ASM: encoding: [0x0d,0x71] +c.addi16sp sp, 0xfffffea0 + +## Branch and Jump immediates are relative but printed as their absolute address +## when disassembling. + +# CHECK-OBJ: c.beqz a2, 0xffffff06 +# CHECK-ASM: c.beqz a2, -256 +# CHECK-ASM: encoding: [0x01,0xd2] +c.beqz a2, 0xffffff00 + +# CHECK-OBJ: c.beqz a0, 0xffffff16 +# CHECK-ASM: .insn cb 1, 6, a0, -242 +# CHECK-ASM: encoding: [0x19,0xd5] +.insn cb 1, 6, a0, 0xffffff0e + +# CHECK-OBJ: c.jal 0xfffffab4 +# CHECK-ASM: c.jal -1366 +# CHECK-ASM: encoding: [0x6d,0x34] +c.jal 0xfffffaaa + +# CHECK-OBJ: c.j 0xfffffcd8 +# CHECK-ASM: .insn cj 1, 5, -820 +# CHECK-ASM: encoding: [0xf1,0xb1] +.insn cj 1, 5, 0xfffffccc diff --git a/llvm/test/MC/RISCV/rv32i-only-valid.s b/llvm/test/MC/RISCV/rv32i-only-valid.s index 806219fd4b37d8..74232e3c419f14 100644 --- a/llvm/test/MC/RISCV/rv32i-only-valid.s +++ b/llvm/test/MC/RISCV/rv32i-only-valid.s @@ -2,7 +2,7 @@ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 < %s \ # RUN: | llvm-objdump -M no-aliases --no-print-imm-hex -d -r - \ -# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: addi a0, a1, -1 # CHECK-ASM: encoding: [0x13,0x85,0xf5,0xff] @@ -16,3 +16,46 @@ lw a1, 0xfffff9ab(a2) # CHECK-ASM-AND-OBJ: sw a1, -8(a2) # CHECK-ASM: encoding: [0x23,0x2c,0xb6,0xfe] sw a1, 0xfffffff8(a2) + +## Branch and Jump immediates are relative but printed as their absolute address +## when disassembling. + +# CHECK-ASM: beq t0, t1, -4096 +# CHECK-ASM: encoding: [0x63,0x80,0x62,0x80] +# CHECK-OBJ: beq t0, t1, 0xfffff010 +beq t0, t1, 0xfffff000 + +# CHECK-ASM: bne t1, t2, -4082 +# CHECK-ASM: encoding: [0x63,0x17,0x73,0x80] +# CHECK-OBJ: bne t1, t2, 0xfffff022 +bne t1, t2, 0xfffff00e + +# CHECK-ASM: beq t2, zero, -3550 +# CHECK-ASM: encoding: [0x63,0x81,0x03,0xa2] +# CHECK-OBJ: beq t2, zero, 0xfffff23a +beqz t2, 0xfffff222 + +# CHECK-ASM: .insn b 99, 0, a0, a1, -3004 +# CHECK-ASM: encoding: [0x63,0x02,0xb5,0xc4] +# CHECK-OBJ: beq a0, a1, 0xfffff460 +.insn b BRANCH, 0, a0, a1, 0xfffff444 + +# CHECK-ASM: jal ra, -2458 +# CHECK-ASM: encoding: [0xef,0xf0,0x6f,0xe6] +# CHECK-OBJ: jal ra, 0xfffff686 +jal ra, 0xfffff666 + +# CHECK-ASM: jal ra, -1912 +# CHECK-ASM: encoding: [0xef,0xf0,0x9f,0x88] +# CHECK-OBJ: jal ra, 0xfffff8ac +jal 0xfffff888 + +# CHECK-ASM: jal zero, -1366 +# CHECK-ASM: encoding: [0x6f,0xf0,0xbf,0xaa] +# CHECK-OBJ: jal zero, 0xfffffad2 +j 0xfffffaaa + +# CHECK-ASM: .insn j 111, a0, -820 +# CHECK-ASM: encoding: [0x6f,0x65,0xe6,0xff] +# CHECK-OBJ: jal a0, 0xfff6682a +.insn j JAL, a0, 0xfffffccc diff --git a/llvm/test/MC/RISCV/rv32zcibop-valid-rv32.s b/llvm/test/MC/RISCV/rv32zcibop-valid-rv32.s new file mode 100644 index 00000000000000..1b6b284d61ae12 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zcibop-valid-rv32.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zicbop -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zicbop < %s \ +# RUN: | llvm-objdump --no-print-imm-hex --mattr=+zicbop -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +## This test checks that 32-bit hex immediates are accepted for the `prefetch.*` +## instructions on rv32. + +# CHECK-ASM-AND-OBJ: prefetch.i -2048(t0) +# CHECK-ASM: encoding: [0x13,0xe0,0x02,0x80] +prefetch.i 0xfffff800(t0) +# CHECK-ASM-AND-OBJ: prefetch.r -2048(t1) +# CHECK-ASM: encoding: [0x13,0x60,0x13,0x80] +prefetch.r 0xfffff800(t1) +# CHECK-ASM-AND-OBJ: prefetch.w -2048(t2) +# CHECK-ASM: encoding: [0x13,0xe0,0x33,0x80] +prefetch.w 0xfffff800(t2)