Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine DMA loads #146

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ad654ba
Add first implementation
long-long-float May 17, 2020
b83a38a
Implement checking the equal difference
long-long-float May 23, 2020
77150c6
Format
long-long-float May 25, 2020
76952cf
Add implementation for other cases
long-long-float May 25, 2020
a5fd0d3
Fix to process at each blocks
long-long-float May 25, 2020
57f4bff
Fix a little
long-long-float Jun 13, 2020
a5a1397
Use memory pitch from the difference
long-long-float Jun 20, 2020
408477a
Fix a little
long-long-float Jun 28, 2020
0a46290
Finished implementation
long-long-float Jul 5, 2020
7a31e86
Fixed a little
long-long-float Jul 12, 2020
70d1d85
Care types other than uchar
long-long-float Jul 19, 2020
fd9fed0
Fix
long-long-float Jul 26, 2020
c39687c
Create new files of ValueExpr
long-long-float Aug 15, 2020
2d18ead
Move combineDMALoads to Combiner
long-long-float Aug 15, 2020
c7358c3
Add a test of CombineDMALoads
long-long-float Aug 18, 2020
a055fbe
Move makeValueBinaryOpFromLocal to ValueExpr.*
long-long-float Aug 23, 2020
6ca4768
Fix a test to check multiple types of vloadn
long-long-float Aug 24, 2020
4bb82e9
Support vloadn other than vload16
long-long-float Aug 24, 2020
86cf23b
Remove deep nests
long-long-float Aug 24, 2020
efebd92
Add test cases and fix
long-long-float Aug 29, 2020
59cd141
Fix test codes
long-long-float Sep 13, 2020
28de130
Fix offset of vloadn
long-long-float Sep 23, 2020
3b3bfb7
Fix a test to check the generic setup
long-long-float Sep 23, 2020
e96cd41
Remove unnecessary method
long-long-float Sep 30, 2020
99961e7
Revert SPIRVHelper.h and .cpp
long-long-float Sep 30, 2020
90c50ca
Fix to use Expression instead of ValueExpr and remove it
long-long-float Sep 30, 2020
6237397
Fix calcValueExpr to take ExpandedExprs
long-long-float Oct 11, 2020
998e468
Write the documentation of combineDMALoads
long-long-float Oct 11, 2020
6e5fafa
Implement replaceLocalToExpr
long-long-float Oct 22, 2020
414e448
Treat `or` as `add`
long-long-float Nov 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix a test to check multiple types of vloadn
long-long-float committed Oct 4, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 6ca4768c12eecebae9e15bcd7de763e741b241b5
157 changes: 93 additions & 64 deletions test/TestOptimizationSteps.cpp
Original file line number Diff line number Diff line change
@@ -5,10 +5,10 @@
*/
#include "TestOptimizationSteps.h"

#include "Bitfield.h"
#include "Expression.h"
#include "Method.h"
#include "Module.h"
#include "Bitfield.h"
#include "intermediate/Helper.h"
#include "intermediate/operators.h"
#include "optimization/Combiner.h"
@@ -1998,86 +1998,115 @@ void TestOptimizationSteps::testLoopInvariantCodeMotion()
void TestOptimizationSteps::testCombineDMALoads()
{
using namespace vc4c::intermediate;
Configuration config{};
Module module{config};
Method inputMethod(module);

auto inIt = inputMethod.createAndInsertNewBlock(inputMethod.end(), "%dummy").walkEnd();

auto in = assign(inIt, TYPE_INT32, "%in") = UNIFORM_REGISTER;

// TODO: Add a case that the first argument of vload16 is a variable.

DataType TYPE16{DataType::WORD, 16, true};

const Local* createLocal(DataType type, const std::string& name) __attribute__((returns_nonnull));
auto res1 = inputMethod.addNewLocal(TYPE16);
auto res2 = inputMethod.addNewLocal(TYPE16);
auto res3 = inputMethod.addNewLocal(TYPE16);
inIt.emplace((new intermediate::MethodCall(std::move(res1), "vload16", {0_val, in})));
inIt.emplace((new intermediate::MethodCall(std::move(res2), "vload16", {1_val, in})));
inIt.emplace((new intermediate::MethodCall(std::move(res3), "vload16", {2_val, in})));
auto testCombineDMALoadsSub = [&](Module& module, Method& inputMethod, Configuration& config, DataType vectorType) {
// TODO: Add a case that the first argument of vload16 is a variable.

const int numOfLoads = 3;
periphery::VPRDMASetup expectedDMASetup(0, 0, numOfLoads, 1, 0);
const int numOfLoads = 3;
periphery::VPRDMASetup expectedDMASetup(0, vectorType.getVectorWidth() % 16, numOfLoads, 1, 0);

combineDMALoads(module, inputMethod, config);
combineDMALoads(module, inputMethod, config);

for(auto& bb : inputMethod)
{
int numOfDMASetup = 0;
int numOfStrideSetup = 0;
int numOfVPMSetup = 0;
int numOfVPMRead = 0;

for(auto& it : bb)
for(auto& bb : inputMethod)
{
if(auto move = dynamic_cast<intermediate::MoveOperation*>(it.get()))
int numOfDMASetup = 0;
int numOfStrideSetup = 0;
int numOfVPMSetup = 0;
int numOfVPMRead = 0;

for(auto& it : bb)
{
auto source = move->getSource();
if(source.getLiteralValue() &&
(move->getOutput()->hasRegister(REG_VPM_IN_SETUP) ||
has_flag(move->decoration, InstructionDecorations::VPM_READ_CONFIGURATION)))
if(auto move = dynamic_cast<intermediate::MoveOperation*>(it.get()))
{
auto dmaSetup = periphery::VPRSetup::fromLiteral(source.getLiteralValue()->unsignedInt()).dmaSetup;
TEST_ASSERT_EQUALS(expectedDMASetup, dmaSetup);
auto source = move->getSource();
if(source.getLiteralValue() &&
(move->getOutput()->hasRegister(REG_VPM_IN_SETUP) ||
has_flag(move->decoration, InstructionDecorations::VPM_READ_CONFIGURATION)))
{
auto dmaSetup =
periphery::VPRSetup::fromLiteral(source.getLiteralValue()->unsignedInt()).dmaSetup;
TEST_ASSERT_EQUALS(expectedDMASetup, dmaSetup);

numOfDMASetup++;
}
else if (auto reg = source.checkRegister())
{
// VPM Read
if (reg->file != RegisterFile::ACCUMULATOR && reg->num == 48)
numOfDMASetup++;
}
else if(auto reg = source.checkRegister())
{
numOfVPMRead++;
// VPM Read
if(reg->file != RegisterFile::ACCUMULATOR && reg->num == 48)
{
numOfVPMRead++;
}
}
}
}
else if (auto load = dynamic_cast<intermediate::LoadImmediate*>(it.get()))
{
if (load->type == LoadType::REPLICATE_INT32 &&
(load->getOutput()->hasRegister(REG_VPM_IN_SETUP) ||
has_flag(load->decoration, InstructionDecorations::VPM_READ_CONFIGURATION)))
else if(auto load = dynamic_cast<intermediate::LoadImmediate*>(it.get()))
{
auto vpr = periphery::VPRSetup::fromLiteral(load->getImmediate().unsignedInt());
if (vpr.isStrideSetup())
{
TEST_ASSERT_EQUALS(64, vpr.strideSetup.getPitch());
numOfStrideSetup++;
}
if (vpr.isGenericSetup())
if(load->type == LoadType::REPLICATE_INT32 &&
(load->getOutput()->hasRegister(REG_VPM_IN_SETUP) ||
has_flag(load->decoration, InstructionDecorations::VPM_READ_CONFIGURATION)))
{
auto vpmSetup = vpr.genericSetup;
TEST_ASSERT_EQUALS(numOfLoads, vpmSetup.getNumber());
numOfVPMSetup++;
auto vpr = periphery::VPRSetup::fromLiteral(load->getImmediate().unsignedInt());
if(vpr.isStrideSetup())
{
TEST_ASSERT_EQUALS(64, vpr.strideSetup.getPitch());
numOfStrideSetup++;
}
if(vpr.isGenericSetup())
{
auto vpmSetup = vpr.genericSetup;
TEST_ASSERT_EQUALS(numOfLoads, vpmSetup.getNumber());
numOfVPMSetup++;
}
}
}
}

TEST_ASSERT_EQUALS(1, numOfDMASetup);
TEST_ASSERT_EQUALS(1, numOfStrideSetup);
TEST_ASSERT_EQUALS(1, numOfVPMSetup);
TEST_ASSERT_EQUALS(numOfLoads, numOfVPMRead);
}
};

auto putMethodCall = [](Method& inputMethod, InstructionWalker& inIt, const DataType& vectorType, std::string funcName, std::vector<Value>&& args) {
auto res = inputMethod.addNewLocal(vectorType);
inIt.emplace((new intermediate::MethodCall(std::move(res), std::move(funcName), std::move(args))));
};

const DataType Float16{DataType::WORD, 16, true};
const DataType Float8 {DataType::WORD, 8, true};

// float16 vload16(size_t, const float*)
const std::string vload16f = "_Z7vload16jPU3AS1Kf";
// float8 vload8(size_t, const float*)
const std::string vload8f = "_Z6vload8jPU3AS1Kf";

Configuration config{};

{
Module module{config};
Method inputMethod(module);

auto inIt = inputMethod.createAndInsertNewBlock(inputMethod.end(), "%dummy").walkEnd();
auto in = assign(inIt, TYPE_INT32, "%in") = UNIFORM_REGISTER;

putMethodCall(inputMethod, inIt, Float16, vload16f, {0_val, in});
putMethodCall(inputMethod, inIt, Float16, vload16f, {1_val, in});
putMethodCall(inputMethod, inIt, Float16, vload16f, {2_val, in});

testCombineDMALoadsSub(module, inputMethod, config, Float16);
}

{
Module module{config};
Method inputMethod(module);

auto inIt = inputMethod.createAndInsertNewBlock(inputMethod.end(), "%dummy").walkEnd();
auto in = assign(inIt, TYPE_INT32, "%in") = UNIFORM_REGISTER;

putMethodCall(inputMethod, inIt, Float8, vload8f, {0_val, in});
putMethodCall(inputMethod, inIt, Float8, vload8f, {1_val, in});
putMethodCall(inputMethod, inIt, Float8, vload8f, {2_val, in});

TEST_ASSERT_EQUALS(1, numOfDMASetup);
TEST_ASSERT_EQUALS(1, numOfStrideSetup);
TEST_ASSERT_EQUALS(1, numOfVPMSetup);
TEST_ASSERT_EQUALS(numOfLoads, numOfVPMRead);
testCombineDMALoadsSub(module, inputMethod, config, Float8);
}
}