Added auxiliar class for multiple activate window pool capturing.
This commit is contained in:
@@ -103,10 +103,11 @@ add_executable(TraceAnalyzer
|
||||
businessObjects/commentmodel.cpp
|
||||
businessObjects/dependencymodels.cpp
|
||||
|
||||
businessObjects/dramTimeDependencies/activatewindowpoolcontroller.cpp
|
||||
businessObjects/dramTimeDependencies/dramtimedependenciesIF.cpp
|
||||
businessObjects/dramTimeDependencies/DDR3TimeDependencies.cpp
|
||||
businessObjects/dramTimeDependencies/dramtimedependencyfactory.cpp
|
||||
businessObjects/phasedependenciestracker.cpp
|
||||
businessObjects/dramTimeDependencies/phasedependenciestracker.cpp
|
||||
|
||||
selectmetrics.ui
|
||||
preferences.ui
|
||||
|
||||
@@ -44,6 +44,9 @@ void DDR3TimeDependencies::mInitializeValues() {
|
||||
dataRate = mMemspecJson["memarchitecturespec"].toObject()["dataRate"].toInt();
|
||||
|
||||
nActivateWindow = 4;
|
||||
|
||||
mPoolSizes.insert({"FAW", 4});
|
||||
|
||||
tRP = tCK * mMemspecJson["memtimingspec"].toObject()["RP"].toInt();
|
||||
tRAS = tCK * mMemspecJson["memtimingspec"].toObject()["RAS"].toInt();
|
||||
tRC = tCK * mMemspecJson["memtimingspec"].toObject()["RC"].toInt();
|
||||
@@ -51,7 +54,7 @@ void DDR3TimeDependencies::mInitializeValues() {
|
||||
tRRD = tCK * mMemspecJson["memtimingspec"].toObject()["RRD"].toInt();
|
||||
tCCD = tCK * mMemspecJson["memtimingspec"].toObject()["CCD"].toInt();
|
||||
tRCD = tCK * mMemspecJson["memtimingspec"].toObject()["RCD"].toInt();
|
||||
tNAW = tCK * mMemspecJson["memtimingspec"].toObject()["FAW"].toInt();
|
||||
tFAW = tCK * mMemspecJson["memtimingspec"].toObject()["FAW"].toInt();
|
||||
tRL = tCK * mMemspecJson["memtimingspec"].toObject()["RL"].toInt();
|
||||
tWL = tCK * mMemspecJson["memtimingspec"].toObject()["WL"].toInt();
|
||||
tWR = tCK * mMemspecJson["memtimingspec"].toObject()["WR"].toInt();
|
||||
@@ -120,7 +123,7 @@ DependencyMap DDR3TimeDependencies::mSpecializedGetDependencies() const {
|
||||
{tXP, "PDXP", DependencyType::IntraRank, "tXP"},
|
||||
{tRFC, "REFAB", DependencyType::IntraRank, "tRFC"},
|
||||
{tXS, "SREFEX", DependencyType::IntraRank, "tXS"},
|
||||
{tNAW, "NAW", DependencyType::IntraRank, "tNAW"}
|
||||
{tFAW, "FAW_POOL", DependencyType::IntraRank, "tFAW"}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -58,7 +58,7 @@ protected:
|
||||
uint tRRD;
|
||||
uint tCCD;
|
||||
uint tRCD;
|
||||
uint tNAW;
|
||||
uint tFAW;
|
||||
uint tRL;
|
||||
uint tWL;
|
||||
uint tWR;
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Iron Prando da Silva
|
||||
*/
|
||||
|
||||
#include "activatewindowpoolcontroller.h"
|
||||
|
||||
ActivateWindowPoolController::ActivateWindowPoolController(const std::map<QString, uint, QStringsComparator>& poolSizes) {
|
||||
mPoolSizes = poolSizes;
|
||||
|
||||
for (const auto& p : poolSizes) {
|
||||
mPools.insert({p.first, {}});
|
||||
mCounts.insert({p.first, 0});
|
||||
mPools[p.first].reserve(32);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ActivateWindowPoolController::clear() {
|
||||
for (auto& p : mPools) {
|
||||
p.second.clear();
|
||||
mCounts[p.first] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ActivateWindowPoolController::push(const QString& poolName, DBDependencyEntry dep) {
|
||||
auto pool = mPools.find(poolName);
|
||||
if (pool != mPools.end()) {
|
||||
pool->second.push_back(dep);
|
||||
mCounts[poolName]++;
|
||||
|
||||
} else {
|
||||
// TODO throw?
|
||||
}
|
||||
}
|
||||
|
||||
void ActivateWindowPoolController::increment(const QString& poolName) {
|
||||
auto pool = mPools.find(poolName);
|
||||
if (pool != mPools.end()) {
|
||||
mCounts[poolName]++;
|
||||
|
||||
} else {
|
||||
// TODO throw?
|
||||
}
|
||||
}
|
||||
|
||||
void ActivateWindowPoolController::merge(std::vector<DBDependencyEntry>& depEntries) {
|
||||
for (const auto& p : mPools) {
|
||||
if(mCounts[p.first] >= mPoolSizes[p.first]) {
|
||||
depEntries.insert( depEntries.end(), p.second.begin(), p.second.end() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Iron Prando da Silva
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commonstructures.h"
|
||||
|
||||
// TODO
|
||||
class ActivateWindowPoolController {
|
||||
public:
|
||||
ActivateWindowPoolController(const std::map<QString, uint, QStringsComparator>& poolSizes);
|
||||
~ActivateWindowPoolController() = default;
|
||||
|
||||
void clear();
|
||||
void push(const QString& poolName, DBDependencyEntry);
|
||||
void increment(const QString& poolName);
|
||||
void merge(std::vector<DBDependencyEntry>& depEntries);
|
||||
|
||||
protected:
|
||||
std::map<QString, std::vector<DBDependencyEntry>, QStringsComparator> mPools;
|
||||
std::map<QString, uint, QStringsComparator> mCounts;
|
||||
std::map<QString, uint, QStringsComparator> mPoolSizes;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Iron Prando da Silva
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "businessObjects/phases/phasedependency.h"
|
||||
|
||||
class TimeDependency {
|
||||
public:
|
||||
TimeDependency() = default;
|
||||
TimeDependency(size_t timeValue, QString phaseDep, DependencyType depType,
|
||||
QString timeDepName, bool considerIntraRank = false)
|
||||
: timeValue{timeValue}, phaseDep{phaseDep}, depType{depType},
|
||||
timeDepName{timeDepName}, considerIntraRank{considerIntraRank} {}
|
||||
|
||||
size_t timeValue;
|
||||
QString phaseDep;
|
||||
DependencyType depType;
|
||||
QString timeDepName;
|
||||
bool considerIntraRank = false; // Used only for InterRank skip check in PhaseDependenciesTracker::mCalculateDependencies
|
||||
|
||||
};
|
||||
|
||||
struct PhaseTimeDependencies {
|
||||
explicit PhaseTimeDependencies(std::initializer_list<TimeDependency> d) : dependencies(d) {}
|
||||
|
||||
std::vector<TimeDependency> dependencies;
|
||||
size_t maxTime;
|
||||
};
|
||||
|
||||
struct QStringsComparator {
|
||||
bool operator()(const QString& s1, const QString& s2);
|
||||
static bool compareQStrings(const QString& s1, const QString& s2);
|
||||
};
|
||||
|
||||
typedef std::map<QString, PhaseTimeDependencies, QStringsComparator> DependencyMap;
|
||||
|
||||
|
||||
struct DBPhaseEntry {
|
||||
size_t id;
|
||||
QString phaseName;
|
||||
size_t phaseBegin;
|
||||
size_t phaseEnd;
|
||||
size_t transact;
|
||||
size_t tBank;
|
||||
size_t tRank;
|
||||
};
|
||||
|
||||
struct DBDependencyEntry {
|
||||
size_t delayedPhaseID;
|
||||
QString delayedPhaseName;
|
||||
QString dependencyType;
|
||||
QString timeDependency;
|
||||
size_t dependencyPhaseID;
|
||||
QString dependencyPhaseName;
|
||||
};
|
||||
@@ -69,6 +69,10 @@ DRAMTimeDependenciesIF::getDependencies(std::vector<QString>& dependencyFilter)
|
||||
return dependenciesMap;
|
||||
}
|
||||
|
||||
ActivateWindowPoolController DRAMTimeDependenciesIF::getAWPools() const {
|
||||
return ActivateWindowPoolController(mPoolSizes);
|
||||
}
|
||||
|
||||
const QJsonObject DRAMTimeDependenciesIF::getMemspec(const TraceDB& tdb, uint& tCK) {
|
||||
QSqlDatabase db = tdb.getDatabase();
|
||||
QString query = "SELECT clk, Memspec FROM GeneralInfo";
|
||||
@@ -101,11 +105,11 @@ void DRAMTimeDependenciesIF::mFilterDependencyList(std::vector<TimeDependency>&
|
||||
dependencyFilter.end(),
|
||||
dep.phaseDep,
|
||||
[](const QString& cmd, const QString& depName){
|
||||
return depName == "NAW" || QStringsComparator::compareQStrings(cmd, depName);
|
||||
return depName.indexOf("_POOL", 3) != -1 || QStringsComparator::compareQStrings(cmd, depName);
|
||||
}
|
||||
);
|
||||
|
||||
if (dep.phaseDep == "NAW" || it != dependencyFilter.end() && *it == dep.phaseDep)
|
||||
if (dep.phaseDep.indexOf("_POOL", 3) != -1 || it != dependencyFilter.end() && *it == dep.phaseDep)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -35,49 +35,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "data/tracedb.h"
|
||||
#include "businessObjects/phases/phasedependency.h"
|
||||
|
||||
class TimeDependency {
|
||||
public:
|
||||
TimeDependency() = default;
|
||||
TimeDependency(size_t timeValue, QString phaseDep, DependencyType depType,
|
||||
QString timeDepName, bool considerIntraRank = false)
|
||||
: timeValue{timeValue}, phaseDep{phaseDep}, depType{depType},
|
||||
timeDepName{timeDepName}, considerIntraRank{considerIntraRank} {}
|
||||
|
||||
size_t timeValue;
|
||||
QString phaseDep;
|
||||
DependencyType depType;
|
||||
QString timeDepName;
|
||||
bool considerIntraRank = false; // Used only for InterRank skip check in PhaseDependenciesTracker::mCalculateDependencies
|
||||
|
||||
};
|
||||
|
||||
struct PhaseTimeDependencies {
|
||||
explicit PhaseTimeDependencies(std::initializer_list<TimeDependency> d) : dependencies(d) {}
|
||||
|
||||
std::vector<TimeDependency> dependencies;
|
||||
size_t maxTime;
|
||||
};
|
||||
|
||||
|
||||
struct QStringsComparator {
|
||||
bool operator()(const QString& s1, const QString& s2);
|
||||
static bool compareQStrings(const QString& s1, const QString& s2);
|
||||
};
|
||||
|
||||
typedef std::map<QString, PhaseTimeDependencies, QStringsComparator> DependencyMap;
|
||||
|
||||
#include "commonstructures.h"
|
||||
#include "activatewindowpoolcontroller.h"
|
||||
|
||||
class DRAMTimeDependenciesIF {
|
||||
public:
|
||||
@@ -91,6 +51,8 @@ public:
|
||||
const uint getClk() const { return tCK; }
|
||||
const uint getNAW() const { return nActivateWindow; };
|
||||
|
||||
ActivateWindowPoolController getAWPools() const;
|
||||
|
||||
protected:
|
||||
void mFilterDependencyList(std::vector<TimeDependency>& dependencyList, const std::vector<QString>& dependencyFilter) const;
|
||||
void mFilterDependencyMap(DependencyMap& dependencyMap, const std::vector<QString>& dependencyFilter) const;
|
||||
@@ -107,5 +69,7 @@ protected:
|
||||
uint tCK = 0;
|
||||
uint nActivateWindow = 0;
|
||||
|
||||
std::map<QString, uint, QStringsComparator> mPoolSizes;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -191,12 +191,10 @@ PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::
|
||||
DependencyMap deviceDependencies = device->getDependencies(commands);
|
||||
|
||||
// Tries to find all timing dependencies for each phase on the trace
|
||||
std::vector<DBDependencyEntry> tmpPotentialNAW;
|
||||
tmpPotentialNAW.reserve(16);
|
||||
ActivateWindowPoolController poolController = device->getAWPools();
|
||||
for (size_t i = 1; i < phases.size(); i++) {
|
||||
// NAW dependencies variables reset
|
||||
tmpPotentialNAW.clear();
|
||||
size_t nawCount = 0;
|
||||
poolController.clear();
|
||||
|
||||
// Auxiliary variables
|
||||
const auto& phase = phases[i];
|
||||
@@ -218,7 +216,8 @@ PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::
|
||||
// For each possible dependency for the current phase,
|
||||
// checks if otherPhase would match as a dependency
|
||||
for (const auto& dep : deps.dependencies) {
|
||||
if (dep.phaseDep != "NAW" && dep.phaseDep != otherPhase->phaseName) continue;
|
||||
int poolSubstrPos = dep.phaseDep.indexOf("_POOL", 3);
|
||||
if (poolSubstrPos == -1 && dep.phaseDep != otherPhase->phaseName) continue;
|
||||
|
||||
bool const skipOnIntraBankAndDifferentBanks = {
|
||||
dep.depType == DependencyType::IntraBank
|
||||
@@ -238,12 +237,15 @@ PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dep.phaseDep == "NAW") {
|
||||
// Captures activate window dependencies
|
||||
if (poolSubstrPos != -1) {
|
||||
if (otherPhase->phaseName == "ACT") {
|
||||
QString poolName = dep.phaseDep.left(poolSubstrPos);
|
||||
|
||||
if (timeDiff == dep.timeValue) {
|
||||
// Captures only the first (or exactly matching time) ACT in
|
||||
// Captures only the first (exactly matching time) ACT in
|
||||
// the ACT window as a dependency
|
||||
tmpPotentialNAW.emplace_back(DBDependencyEntry{
|
||||
poolController.push(poolName, DBDependencyEntry{
|
||||
phase->id,
|
||||
phase->phaseName,
|
||||
PhaseDependency::dependencyTypeName(dep.depType),
|
||||
@@ -253,8 +255,8 @@ PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::
|
||||
});
|
||||
}
|
||||
|
||||
if (timeDiff <= dep.timeValue) {
|
||||
nawCount++;
|
||||
if (timeDiff < dep.timeValue) {
|
||||
poolController.increment(poolName);
|
||||
|
||||
}
|
||||
|
||||
@@ -289,10 +291,7 @@ PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (nawCount >= device->getNAW()) {
|
||||
entries.insert( entries.end(), tmpPotentialNAW.begin(), tmpPotentialNAW.end() );
|
||||
}
|
||||
poolController.merge(entries);
|
||||
|
||||
}
|
||||
|
||||
@@ -40,26 +40,8 @@
|
||||
#include <QString>
|
||||
|
||||
#include "data/tracedb.h"
|
||||
#include "dramTimeDependencies/dramtimedependencyfactory.h"
|
||||
|
||||
struct DBPhaseEntry {
|
||||
size_t id;
|
||||
QString phaseName;
|
||||
size_t phaseBegin;
|
||||
size_t phaseEnd;
|
||||
size_t transact;
|
||||
size_t tBank;
|
||||
size_t tRank;
|
||||
};
|
||||
|
||||
struct DBDependencyEntry {
|
||||
size_t delayedPhaseID;
|
||||
QString delayedPhaseName;
|
||||
QString dependencyType;
|
||||
QString timeDependency;
|
||||
size_t dependencyPhaseID;
|
||||
QString dependencyPhaseName;
|
||||
};
|
||||
#include "dramtimedependencyfactory.h"
|
||||
#include "commonstructures.h"
|
||||
|
||||
class PhaseDependenciesTracker {
|
||||
public:
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include "businessObjects/configmodels.h"
|
||||
#include "businessObjects/pythoncaller.h"
|
||||
#include "businessObjects/phasedependenciestracker.h"
|
||||
#include "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
|
||||
#include "presentation/traceselector.h"
|
||||
#include "qmessagebox.h"
|
||||
#include "queryeditor.h"
|
||||
|
||||
Reference in New Issue
Block a user