split-join fix for unanimous branches
This commit is contained in:
@@ -55,16 +55,17 @@ namespace Harp {
|
|||||||
DomStackEntry(
|
DomStackEntry(
|
||||||
unsigned p, const std::vector<std::vector<Reg<bool> > >& m,
|
unsigned p, const std::vector<std::vector<Reg<bool> > >& m,
|
||||||
std::vector<bool> &tm, Word pc
|
std::vector<bool> &tm, Word pc
|
||||||
): pc(pc), fallThrough(false)
|
): pc(pc), fallThrough(false), uni(false)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < m.size(); ++i)
|
for (unsigned i = 0; i < m.size(); ++i)
|
||||||
tmask.push_back(!bool(m[i][p]) && tm[i]);
|
tmask.push_back(!bool(m[i][p]) && tm[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DomStackEntry(const std::vector<bool> &tmask):
|
DomStackEntry(const std::vector<bool> &tmask):
|
||||||
tmask(tmask), fallThrough(true) {}
|
tmask(tmask), fallThrough(true), uni(false) {}
|
||||||
|
|
||||||
bool fallThrough;
|
bool fallThrough;
|
||||||
|
bool uni;
|
||||||
std::vector<bool> tmask;
|
std::vector<bool> tmask;
|
||||||
Word pc;
|
Word pc;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -112,6 +112,28 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool checkUnanimous(unsigned p, const std::vector<std::vector<Reg<bool> > >& m,
|
||||||
|
const std::vector<bool> &tm) {
|
||||||
|
bool same;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < m.size(); ++i) {
|
||||||
|
if (tm[i]) {
|
||||||
|
same = m[i][p];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == m.size())
|
||||||
|
throw DivergentBranchException();
|
||||||
|
for (; i < m.size(); ++i) {
|
||||||
|
if (tm[i]) {
|
||||||
|
if (same != (bool(m[i][p]))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Instruction::executeOn(Warp &c) {
|
void Instruction::executeOn(Warp &c) {
|
||||||
D(3, "Begin instruction execute.");
|
D(3, "Begin instruction execute.");
|
||||||
|
|
||||||
@@ -345,7 +367,12 @@ void Instruction::executeOn(Warp &c) {
|
|||||||
break;
|
break;
|
||||||
case SPLIT: if (sjOnce) {
|
case SPLIT: if (sjOnce) {
|
||||||
sjOnce = false;
|
sjOnce = false;
|
||||||
// TODO: if mask becomes all-zero, fall through
|
if (checkUnanimous(pred, c.pred, c.tmask)) {
|
||||||
|
DomStackEntry e(c.tmask);
|
||||||
|
e.uni = true;
|
||||||
|
c.domStack.push(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
DomStackEntry e(pred, c.pred, c.tmask, c.pc);
|
DomStackEntry e(pred, c.pred, c.tmask, c.pc);
|
||||||
c.domStack.push(c.tmask);
|
c.domStack.push(c.tmask);
|
||||||
c.domStack.push(e);
|
c.domStack.push(e);
|
||||||
@@ -355,7 +382,12 @@ void Instruction::executeOn(Warp &c) {
|
|||||||
break;
|
break;
|
||||||
case JOIN: if (sjOnce) {
|
case JOIN: if (sjOnce) {
|
||||||
sjOnce = false;
|
sjOnce = false;
|
||||||
// TODO: if mask becomes all-zero, fall through
|
if (!c.domStack.empty() && c.domStack.top().uni) {
|
||||||
|
D(2, "Uni branch at join");
|
||||||
|
c.tmask = c.domStack.top().tmask;
|
||||||
|
c.domStack.pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!c.domStack.top().fallThrough) {
|
if (!c.domStack.top().fallThrough) {
|
||||||
if (!pcSet) nextPc = c.domStack.top().pc;
|
if (!pcSet) nextPc = c.domStack.top().pc;
|
||||||
pcSet = true;
|
pcSet = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user