1 // Copyright 2017-2019 VMware, Inc. 2 // SPDX-License-Identifier: BSD-2-Clause 3 // 4 // The BSD-2 license (the License) set forth below applies to all parts of the 5 // Cascade project. You may not use this file except in compliance with the 6 // License. 7 // 8 // BSD-2 License 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions are met: 12 // 13 // 1. Redistributions of source code must retain the above copyright notice, this 14 // list of conditions and the following disclaimer. 15 // 16 // 2. Redistributions in binary form must reproduce the above copyright notice, 17 // this list of conditions and the following disclaimer in the documentation 18 // and/or other materials provided with the distribution. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND 21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #ifndef CASCADE_SRC_TARGET_COMPILER_H 32 #define CASCADE_SRC_TARGET_COMPILER_H 33 34 #include <mutex> 35 #include <set> 36 #include <string> 37 #include <unordered_map> 38 #include <unordered_set> 39 #include "runtime/runtime.h" 40 #include "verilog/ast/ast_fwd.h" 41 #include "verilog/ast/visitors/visitor.h" 42 43 namespace cascade { 44 45 class CoreCompiler; 46 class Engine; 47 class Interface; 48 49 class Compiler { 50 public: 51 Compiler(); 52 virtual ~Compiler(); 53 54 // Configuration Interface: 55 // 56 // These methods are not thread-safe. The results on invoking these methods 57 // after the first invocation of compile() or to replace a previously 58 // registered compiler are undefined. 59 Compiler& set(const std::string& id, CoreCompiler* c); 60 CoreCompiler* get(const std::string& id); 61 62 // Compilation Interface: 63 // 64 // These methods are all thread-safe and return immediately. 65 // 66 // Ignores md and returns an engine backed by a StubCore. This method does 67 // not take ownership of md and is undefined for modules with incompatible 68 // __loc annotations. 69 Engine* compile_stub(Engine::Id id, const ModuleDeclaration* md); 70 // Compiles md using the core compiler specified by the __target 71 // annotation. This method takes ownership of md. 72 Engine* compile(Engine::Id id, ModuleDeclaration* md); 73 // Causes all invocations of compile() associated with id to return in a 74 // *reasonably short* amount of time. If an invocation of compile() would 75 // return normally it may do so, otherwise, it will return nullptr. 76 void stop_compile(Engine::Id id); 77 // Causes all invocations of compile() to return in a *reasonably short* 78 // amount of time. If an invocation of compile() would return normally it 79 // may do so, otherwise, it will return nullptr. 80 void stop_compile(); 81 // Invokes stop_async() on all registered compilers. 82 void stop_async(); 83 84 // Error Reporting Interface: 85 // 86 // These methods are all thread safe and report errors if any in-flight 87 // compilations encountered an error. 88 void error(const std::string& s); 89 void fatal(const std::string& s); 90 bool error(); 91 std::pair<bool, std::string> what(); 92 void clear(); 93 94 // Scheduling Interface: 95 // 96 // Schedules a blocking interrupt in a state safe window defined by all 97 // registered compilers. This method is thread safe, but should only be 98 // invoked by second-pass jit-compilers. Invoking this method in a first- 99 // pass compiler will cause the runtime to hang. 100 virtual void schedule_state_safe_interrupt(Runtime::Interrupt int_) = 0; 101 102 protected: 103 // Interface Compilation... Interface: 104 // 105 // Sanity checks the __loc annotation on a module declaration and returns 106 // either the interface provided by this compiler or nullptr. 107 virtual Interface* get_interface(const std::string& loc) = 0; 108 109 private: 110 // Checks whether a module is a stub: a module with no inputs or outputs, 111 // and no runtime-visible side-effects. 112 class StubCheck : public Visitor { 113 public: 114 ~StubCheck() override = default; 115 bool check(const ModuleDeclaration* md); 116 private: 117 bool stub_; 118 void visit(const InitialConstruct* ic) override; 119 void visit(const FinishStatement* fs) override; 120 void visit(const RestartStatement* rs) override; 121 void visit(const RetargetStatement* rs) override; 122 void visit(const SaveStatement* ss) override; 123 }; 124 125 // Compilers: 126 std::unordered_map<std::string, CoreCompiler*> ccs_; 127 128 // Compilation State: 129 std::unordered_set<Engine::Id> ids_; 130 131 // Error State: 132 std::mutex lock_; 133 bool fatal_; 134 std::string what_; 135 }; 136 137 } // namespace cascade 138 139 #endif 140