diff options
author | jeanPerier <jperier@nvidia.com> | 2024-04-02 14:29:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-02 14:29:29 +0200 |
commit | a4798bb0b67533b37d6b34fd5292714aac3b17d9 (patch) | |
tree | 4c2aba998e0b1ffdce015955f0bad3ba86646e1b /flang/lib/Lower/Bridge.cpp | |
parent | 2950283dddab03c183c1be2d7de9d4999cc86131 (diff) | |
download | llvm-a4798bb0b67533b37d6b34fd5292714aac3b17d9.zip llvm-a4798bb0b67533b37d6b34fd5292714aac3b17d9.tar.gz llvm-a4798bb0b67533b37d6b34fd5292714aac3b17d9.tar.bz2 |
[flang][NFC] use mlir::SymbolTable in lowering (#86673)
Whenever lowering is checking if a function or global already exists in
the mlir::Module, it was doing module->lookup.
On big programs (~5000 globals and functions), this causes important
slowdowns because these lookups are linear. Use mlir::SymbolTable to
speed-up these lookups. The SymbolTable has to be created from the
ModuleOp and maintained in sync. It is therefore placed in the
converter, and FirOPBuilders can take a pointer to it to speed-up the
lookups.
This patch does not bring mlir::SymbolTable to FIR/HLFIR passes, but
some passes creating a lot of runtime calls could benefit from it too.
More analysis will be needed.
As an example of the speed-ups, this patch speeds-up compilation of
Whizard compare_amplitude_UFO.F90 from 5 mins to 2 mins on my machine
(there is still room for speed-ups).
Diffstat (limited to 'flang/lib/Lower/Bridge.cpp')
-rw-r--r-- | flang/lib/Lower/Bridge.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 91b898e..5bba097 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -273,7 +273,8 @@ class FirConverter : public Fortran::lower::AbstractConverter { public: explicit FirConverter(Fortran::lower::LoweringBridge &bridge) : Fortran::lower::AbstractConverter(bridge.getLoweringOptions()), - bridge{bridge}, foldingContext{bridge.createFoldingContext()} {} + bridge{bridge}, foldingContext{bridge.createFoldingContext()}, + mlirSymbolTable{bridge.getModule()} {} virtual ~FirConverter() = default; /// Convert the PFT to FIR. @@ -329,8 +330,8 @@ public: [&](Fortran::lower::pft::BlockDataUnit &b) {}, [&](Fortran::lower::pft::CompilerDirectiveUnit &d) {}, [&](Fortran::lower::pft::OpenACCDirectiveUnit &d) { - builder = new fir::FirOpBuilder(bridge.getModule(), - bridge.getKindMap()); + builder = new fir::FirOpBuilder( + bridge.getModule(), bridge.getKindMap(), &mlirSymbolTable); Fortran::lower::genOpenACCRoutineConstruct( *this, bridge.getSemanticsContext(), bridge.getModule(), d.routine, accRoutineInfos); @@ -1036,6 +1037,8 @@ private: return {}; } + mlir::SymbolTable *getMLIRSymbolTable() override { return &mlirSymbolTable; } + /// Add the symbol to the local map and return `true`. If the symbol is /// already in the map and \p forced is `false`, the map is not updated. /// Instead the value `false` is returned. @@ -4571,7 +4574,8 @@ private: llvm::dbgs() << "\n"); Fortran::lower::CalleeInterface callee(funit, *this); mlir::func::FuncOp func = callee.addEntryBlockAndMapArguments(); - builder = new fir::FirOpBuilder(func, bridge.getKindMap()); + builder = + new fir::FirOpBuilder(func, bridge.getKindMap(), &mlirSymbolTable); assert(builder && "FirOpBuilder did not instantiate"); builder->setFastMathFlags(bridge.getLoweringOptions().getMathOptions()); builder->setInsertionPointToStart(&func.front()); @@ -4839,12 +4843,14 @@ private: // FIXME: get rid of the bogus function context and instantiate the // globals directly into the module. mlir::MLIRContext *context = &getMLIRContext(); + mlir::SymbolTable *symbolTable = getMLIRSymbolTable(); mlir::func::FuncOp func = fir::FirOpBuilder::createFunction( mlir::UnknownLoc::get(context), getModuleOp(), fir::NameUniquer::doGenerated("Sham"), - mlir::FunctionType::get(context, std::nullopt, std::nullopt)); + mlir::FunctionType::get(context, std::nullopt, std::nullopt), + symbolTable); func.addEntryBlock(); - builder = new fir::FirOpBuilder(func, bridge.getKindMap()); + builder = new fir::FirOpBuilder(func, bridge.getKindMap(), symbolTable); assert(builder && "FirOpBuilder did not instantiate"); builder->setFastMathFlags(bridge.getLoweringOptions().getMathOptions()); createGlobals(); @@ -5336,6 +5342,11 @@ private: /// utilities to deal with procedure pointer components whose arguments have /// the type of the containing derived type. Fortran::lower::TypeConstructionStack typeConstructionStack; + /// MLIR symbol table of the fir.global/func.func operations. Note that it is + /// not guaranteed to contain all operations of the ModuleOp with Symbol + /// attribute since mlirSymbolTable must pro-actively be maintained when + /// new Symbol operations are created. + mlir::SymbolTable mlirSymbolTable; }; } // namespace |