34 #ifndef MC2LIB_CODEGEN_COMPILER_HPP_ 35 #define MC2LIB_CODEGEN_COMPILER_HPP_ 44 #include <unordered_map> 45 #include <unordered_set> 49 #include "../memconsistency/eventsets.hpp" 50 #include "../types.hpp" 60 namespace mc = memconsistency;
62 template <std::
size_t max_size_bytes>
66 template <
class... Ts>
76 template <
class Backend,
class EvtStateT>
82 typedef std::shared_ptr<Op>
Ptr;
84 typedef typename Thread::const_iterator
ThreadIt;
85 typedef std::unordered_map<types::Pid, Thread>
Threads;
94 typedef std::function<std::size_t(
Op *,
types::InstPtr, Backend *, EvtState *,
102 std::unordered_set<Op *> used;
104 for (
auto &op : (*container)) {
105 assert(op !=
nullptr);
107 if (used.insert(op.get()).second) {
112 result[op->pid()].emplace_back(op);
119 std::size_t result = 0;
121 for (
const auto &thread : threads) {
122 result += thread.second.size();
134 ++(it_stack->back().first);
140 virtual Ptr
Clone()
const = 0;
146 virtual void Reset() = 0;
164 virtual void InsertPo(ThreadConstIt before, EvtState *evts) = 0;
186 EvtState *evts,
void *code, std::size_t len) = 0;
200 EvtState *evts)
const = 0;
213 EvtState *evts)
const = 0;
244 template <
class Backend,
class EvtState>
252 template <
class Backend,
class EvtState>
261 throw std::logic_error(
"Not supported");
265 void *code, std::size_t len)
override {
266 throw std::logic_error(
"Not supported");
273 throw std::logic_error(
"Not supported");
279 throw std::logic_error(
"Not supported");
285 throw std::logic_error(
"Not supported");
293 template <
class Operation,
class Backend>
312 explicit Compiler(std::unique_ptr<EvtState> evts) : evts_(std::move(evts)) {
326 explicit Compiler(std::unique_ptr<EvtState> evts, Threads &&threads)
327 : evts_(std::move(evts)) {
328 Reset(std::move(threads));
338 threads_ = std::move(threads);
341 for (
const auto &thread : threads_) {
342 for (
const auto &op : thread.second) {
352 const EvtState *
evts()
const {
return evts_.get(); }
354 EvtState *
evts() {
return evts_.get(); }
357 std::size_t len, ThreadConst *thread_const_ops,
358 CallbackStack *callback_stack) {
360 if (!op->EnableEmit(evts_.get())) {
365 if (thread_const_ops !=
nullptr) {
366 assert(!thread_const_ops->empty());
367 op->InsertPo(--thread_const_ops->end(), evts_.get());
368 thread_const_ops->push_back(op);
370 ThreadConst invalid{
nullptr};
371 op->InsertPo(invalid.begin(), evts_.get());
374 std::size_t ctrl_len = 0;
376 if (callback_stack !=
nullptr) {
378 for (
auto &callback : (*callback_stack)) {
381 const std::size_t s =
382 callback(op, base, &backend_, evts_.get(), code, len);
386 code =
static_cast<char *
>(code) + s;
392 op->RegisterCallback(callback_stack);
396 const std::size_t op_len =
397 op->Emit(base, &backend_, evts_.get(), code, len);
401 assert(IpToOp(base) ==
nullptr);
403 ip_to_op_[base] = std::make_pair(base + op_len, op);
405 return op_len + ctrl_len;
410 auto thread = threads_.find(pid);
412 if (thread == threads_.end()) {
416 std::size_t emit_len = 0;
422 ThreadConst thread_const_ops{
nullptr};
423 thread_const_ops.reserve(thread->second.size() + 1);
426 CallbackStack callback_stack;
429 ThreadItStack it_stack;
430 it_stack.emplace_back(thread->second.begin(), thread->second.end());
432 while (!it_stack.empty()) {
433 auto &it = it_stack.back().first;
434 auto &end = it_stack.back().second;
441 const auto &op = *it;
444 const std::size_t op_len =
445 Emit(base + emit_len, op.get(), code, len - emit_len,
446 &thread_const_ops, &callback_stack);
449 assert(emit_len <= len);
450 code =
static_cast<char *
>(code) + op_len;
452 op->AdvanceThread(&it_stack);
456 for (
auto &callback : callback_stack) {
457 const std::size_t s = callback(
nullptr, base + emit_len, &backend_,
458 evts_.get(), code, len - emit_len);
461 assert(emit_len <= len);
462 code =
static_cast<char *
>(code) + s;
470 auto op = IpToOp(ip);
476 return op->UpdateObs(ip, part, addr, from_id, size, evts_.get());
480 if (ip_to_op_.empty()) {
489 auto e = ip_to_op_.upper_bound(ip);
490 if (e != ip_to_op_.begin()) {
494 if (!(e->first <= ip && ip < e->second.first)) {
498 return e->second.second;
502 typedef std::map<types::InstPtr, std::pair<types::InstPtr, Operation *>>
virtual bool EnableEmit(EvtState *evts)=0
Operation::ThreadItStack ThreadItStack
Definition: compiler.hpp:299
Operation::Callback Callback
Definition: compiler.hpp:301
EvtState * evts()
Definition: compiler.hpp:354
auto MakeEventPtrs(const mc::Event *e1, Ts... en) -> EventPtrs<(1+sizeof...(Ts)) *sizeof(types::WriteID)>
Definition: compiler.hpp:67
std::size_t Emit(types::InstPtr base, Operation *op, void *code, std::size_t len, ThreadConst *thread_const_ops, CallbackStack *callback_stack)
Definition: compiler.hpp:356
std::vector< const Op * > ThreadConst
Definition: compiler.hpp:89
std::size_t Emit(types::InstPtr start, Backend *backend, EvtState *evts, void *code, std::size_t len) override
Definition: compiler.hpp:264
bool UpdateObs(types::InstPtr ip, int part, types::Addr addr, const types::WriteID *from_id, std::size_t size)
Definition: compiler.hpp:468
Operation::ThreadConst ThreadConst
Definition: compiler.hpp:300
EvtStateT EvtState
Definition: compiler.hpp:79
Thread::const_iterator ThreadIt
Definition: compiler.hpp:84
std::unordered_map< types::Pid, Thread > Threads
Definition: compiler.hpp:85
void Reset()
Definition: compiler.hpp:331
Operation::ThreadIt ThreadIt
Definition: compiler.hpp:298
void Reset(Threads &&threads)
Definition: compiler.hpp:337
std::map< types::InstPtr, std::pair< types::InstPtr, Operation * > > InstPtr_Op
Definition: compiler.hpp:503
Definition: compiler.hpp:77
std::vector< Callback > CallbackStack
Definition: compiler.hpp:97
const mc::Event * FirstEvent(const mc::Event *prev_event, EvtState *evts) const override
Definition: compiler.hpp:283
void InsertPo(typename Op< Backend, EvtState >::ThreadConstIt before, EvtState *evts) override
Definition: compiler.hpp:259
Threads threads_
Definition: compiler.hpp:507
std::function< std::size_t(Op *, types::InstPtr, Backend *, EvtState *, void *, std::size_t)> Callback
Definition: compiler.hpp:96
friend Threads ExtractThreads(T *container)
Definition: compiler.hpp:100
Operation::EvtState EvtState
Definition: compiler.hpp:296
virtual bool UpdateObs(types::InstPtr ip, int part, types::Addr addr, const types::WriteID *from_id, std::size_t size, EvtState *evts)=0
Types< true >::InstPtr InstPtr
Instruction pointer type.
Definition: types.hpp:81
virtual Ptr Clone() const =0
virtual ~Op()
Definition: compiler.hpp:131
Top level class used to manage code generation (compiler).
Definition: compiler.hpp:294
Definition: eventsets.hpp:103
virtual const mc::Event * LastEvent(const mc::Event *next_event, EvtState *evts) const =0
ThreadConst::const_iterator ThreadConstIt
Definition: compiler.hpp:90
std::vector< Ptr > Thread
Definition: compiler.hpp:83
std::unique_ptr< EvtState > evts_
Definition: compiler.hpp:505
std::vector< std::pair< ThreadIt, ThreadIt > > ThreadItStack
Definition: compiler.hpp:86
NullOp(types::Pid pid)
Definition: compiler.hpp:255
virtual void InsertPo(ThreadConstIt before, EvtState *evts)=0
Definition: compiler.hpp:245
Op< Backend, EvtStateCats > Operation
Definition: armv7.hpp:211
Compiler(std::unique_ptr< EvtState > evts)
Definition: compiler.hpp:312
Operation::Threads Threads
Definition: compiler.hpp:297
Definition: compiler.hpp:253
bool UpdateObs(types::InstPtr ip, int part, types::Addr addr, const types::WriteID *from_id, std::size_t size, EvtState *evts) override
Definition: compiler.hpp:270
std::array< const mc::Event *, max_size_bytes/sizeof(types::WriteID)> EventPtrs
Definition: compiler.hpp:64
const mc::Event * LastEvent(const mc::Event *next_event, EvtState *evts) const override
Definition: compiler.hpp:277
const EvtState * evts() const
Definition: compiler.hpp:352
virtual void AdvanceThread(ThreadItStack *it_stack) const
Definition: compiler.hpp:133
bool EnableEmit(EvtState *evts) override
Definition: compiler.hpp:257
Types< true >::WriteID WriteID
Write ID type.
Definition: types.hpp:86
Op(types::Pid pid)
Definition: compiler.hpp:129
Types< true >::Addr Addr
Address type.
Definition: types.hpp:66
virtual void RegisterCallback(CallbackStack *callback_stack)
Definition: compiler.hpp:172
const Threads & threads()
Definition: compiler.hpp:350
std::shared_ptr< Op > Ptr
Definition: compiler.hpp:82
Compiler(std::unique_ptr< EvtState > evts, Threads &&threads)
Definition: compiler.hpp:326
Types< true >::Pid Pid
Processor/thread ID type.
Definition: types.hpp:71
virtual const mc::Event * FirstEvent(const mc::Event *prev_event, EvtState *evts) const =0
types::Pid pid_
Definition: compiler.hpp:241
Operation::CallbackStack CallbackStack
Definition: compiler.hpp:302
Backend backend_
Definition: compiler.hpp:506
friend std::size_t threads_size(const Threads &threads)
Definition: compiler.hpp:118
types::Pid pid() const
Definition: compiler.hpp:236
InstPtr_Op ip_to_op_
Definition: compiler.hpp:511
void set_pid(types::Pid pid)
Definition: compiler.hpp:238
Operation * IpToOp(types::InstPtr ip) const
Definition: compiler.hpp:479
virtual std::size_t Emit(types::InstPtr start, Backend *backend, EvtState *evts, void *code, std::size_t len)=0
std::size_t Emit(types::Pid pid, types::InstPtr base, void *code, std::size_t len)
Definition: compiler.hpp:408
MemOp(types::Pid pid)
Definition: compiler.hpp:247