verilator/src/V3Partition.h
Geza Lore a8f83d5758
Construct AstExecGraph implementation outside of V3EmitC. (#3022)
The goal of this patch is to move functionality related to constructing
the thread entry points and then invoking them out of V3EmitC (and into
V3Partition). The long term goal being enabling V3EmitC to emit
functions partitioned based on header dependencies. V3EmitC having to
deal with only AstCFunc instances and no other magic will facilitate
this.

In this patch:
- We construct AstCFuncs for each thread entry point in
V3Partition::finalize and move AstMTaskBody nodes under these functions.
- Add the invocation of the threads as text statements within the
AstExecGraph, so they are still invoked where the exec graph is located.
(the entry point functions are still referenced via AstCCall or
AstAddOrCFunc, so lazy declarations of referenced functions are created
automatically).
- Explicitly handle MTask state variables (VlMTaskVertex in
verilated_threads.h) within Verilator, so no need to text bash a lot of
these any more (some text refs still remain but they are all created
next to each other within V3Partition.cpp).

The effect of all this on the emitted code should be nothing but some
identifier/ordering changes. No functional change intended.
2021-06-16 12:18:56 +01:00

95 lines
2.9 KiB
C++

// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Threading's logic to mtask partitioner
//
// Code available from: https://verilator.org
//
//*************************************************************************
//
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#ifndef VERILATOR_V3PARTITION_H_
#define VERILATOR_V3PARTITION_H_
#include "config_build.h"
#include "verilatedos.h"
#include "V3Graph.h"
#include "V3OrderGraph.h"
#include <list>
class LogicMTask;
using Vx2MTaskMap = std::unordered_map<const MTaskMoveVertex*, LogicMTask*>;
//*************************************************************************
/// V3Partition takes the fine-grained logic graph from V3Order and
/// collapses it into a coarse-grained graph of AbstractLogicMTask's, each
/// of which contains of set of the logic nodes from the fine-grained
/// graph.
class V3Partition final {
// MEMBERS
V3Graph* m_fineDepsGraphp; // Fine-grained dependency graph
public:
// CONSTRUCTORS
explicit V3Partition(V3Graph* fineDepsGraphp)
: m_fineDepsGraphp{fineDepsGraphp} {}
~V3Partition() = default;
// METHODS
// Fill in the provided empty graph with AbstractLogicMTask's and their
// interdependencies.
void go(V3Graph* mtasksp);
static void selfTest();
// Print out a hash of the shape of graphp. Only needed to debug the
// origin of some nondeterminism; otherwise this is pretty useless.
static void hashGraphDebug(const V3Graph* graphp, const char* debugName);
// Print debug stats about graphp whose nodes must be AbstractMTask's.
static void debugMTaskGraphStats(const V3Graph* graphp, const string& stage);
// Operate on the final ExecMTask graph, immediately prior to code
// generation time.
static void finalize();
private:
static void setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp);
VL_DEBUG_FUNC; // Declare debug()
VL_UNCOPYABLE(V3Partition);
};
//*************************************************************************
// Map a pointer into a id, for e.g. nodep to mtask mappings
class PartPtrIdMap final {
private:
// TYPES
// MEMBERS
mutable vluint64_t m_nextId = 0;
mutable std::unordered_map<const void*, vluint64_t> m_id;
public:
// CONSTRUCTORS
PartPtrIdMap() = default;
// METHODS
vluint64_t findId(const void* ptrp) const {
const auto it = m_id.find(ptrp);
if (it != m_id.end()) return it->second;
m_id[ptrp] = m_nextId;
return m_nextId++;
}
};
#endif // Guard