forked from github/verilator
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.
95 lines
2.9 KiB
C++
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
|