1 //===- IRTransformLayer.h - Run all IR through a functor --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Run all IR passed in through a user supplied functor.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
16 
17 #include "llvm/ExecutionEngine/JITSymbol.h"
18 #include "llvm/ExecutionEngine/Orc/Layer.h"
19 #include <memory>
20 #include <string>
21 
22 namespace llvm {
23 class Module;
24 namespace orc {
25 
26 class IRTransformLayer2 : public IRLayer {
27 public:
28 
29   using TransformFunction =
30     std::function<Expected<std::unique_ptr<Module>>(std::unique_ptr<Module>)>;
31 
32   IRTransformLayer2(ExecutionSession &ES, IRLayer &BaseLayer,
33                     TransformFunction Transform = identityTransform);
34 
setTransform(TransformFunction Transform)35   void setTransform(TransformFunction Transform) {
36     this->Transform = std::move(Transform);
37   }
38 
39   void emit(MaterializationResponsibility R, VModuleKey K,
40             std::unique_ptr<Module> M) override;
41 
identityTransform(std::unique_ptr<Module> M)42   static std::unique_ptr<Module> identityTransform(std::unique_ptr<Module> M) {
43     return M;
44   }
45 
46 private:
47   IRLayer &BaseLayer;
48   TransformFunction Transform;
49 };
50 
51 /// IR mutating layer.
52 ///
53 ///   This layer applies a user supplied transform to each module that is added,
54 /// then adds the transformed module to the layer below.
55 template <typename BaseLayerT, typename TransformFtor>
56 class IRTransformLayer {
57 public:
58 
59   /// Construct an IRTransformLayer with the given BaseLayer
60   IRTransformLayer(BaseLayerT &BaseLayer,
61                    TransformFtor Transform = TransformFtor())
BaseLayer(BaseLayer)62     : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
63 
64   /// Apply the transform functor to the module, then add the module to
65   ///        the layer below, along with the memory manager and symbol resolver.
66   ///
67   /// @return A handle for the added modules.
addModule(VModuleKey K,std::unique_ptr<Module> M)68   Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
69     return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
70   }
71 
72   /// Remove the module associated with the VModuleKey K.
removeModule(VModuleKey K)73   Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
74 
75   /// Search for the given named symbol.
76   /// @param Name The name of the symbol to search for.
77   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
78   /// @return A handle for the given named symbol, if it exists.
findSymbol(const std::string & Name,bool ExportedSymbolsOnly)79   JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
80     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
81   }
82 
83   /// Get the address of the given symbol in the context of the module
84   ///        represented by the VModuleKey K. This call is forwarded to the base
85   ///        layer's implementation.
86   /// @param K The VModuleKey for the module to search in.
87   /// @param Name The name of the symbol to search for.
88   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
89   /// @return A handle for the given named symbol, if it is found in the
90   ///         given module.
findSymbolIn(VModuleKey K,const std::string & Name,bool ExportedSymbolsOnly)91   JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
92                          bool ExportedSymbolsOnly) {
93     return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
94   }
95 
96   /// Immediately emit and finalize the module represented by the given
97   ///        VModuleKey.
98   /// @param K The VModuleKey for the module to emit/finalize.
emitAndFinalize(VModuleKey K)99   Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
100 
101   /// Access the transform functor directly.
getTransform()102   TransformFtor& getTransform() { return Transform; }
103 
104   /// Access the mumate functor directly.
getTransform()105   const TransformFtor& getTransform() const { return Transform; }
106 
107 private:
108   BaseLayerT &BaseLayer;
109   TransformFtor Transform;
110 };
111 
112 } // end namespace orc
113 } // end namespace llvm
114 
115 #endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
116