Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 8 additions & 4 deletions src/RegisterAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,13 +457,17 @@ bool RegisterAllocator::processBranchState( BranchState* state, std::list<Token>

std::list<Token>::iterator target;

// the path runs up to the token after the branch, or to the branch
// itself when it ends the program
Token& after = (curr != end) ? *curr : token;

if( token.operand()->flags() & Operand::DYNAMIC )
{
if( !state->address( *branchDest, target, m_labels ) )
continue;

unsigned int targetLine = (*target).lineNumber();
unsigned int currentLine = (*curr).lineNumber();
unsigned int currentLine = after.lineNumber();
bool isBackwardBranch = targetLine < currentLine;

if( state->isBranchTaken( &*target ) )
Expand All @@ -490,7 +494,7 @@ bool RegisterAllocator::processBranchState( BranchState* state, std::list<Token>
BranchState* newState = new BranchState( *state );
assert( newState );

newState->pushTraces( &*curr, false );
newState->pushTraces( &after, false );
newState->pushTraces( &*target, true );
newState->setCurrent( target );

Expand All @@ -505,15 +509,15 @@ bool RegisterAllocator::processBranchState( BranchState* state, std::list<Token>
{
// Backward branch (loop back-edge) - extend live ranges to cover loop body
unsigned int targetLine = (*target).lineNumber();
unsigned int currentLine = (*curr).lineNumber();
unsigned int currentLine = after.lineNumber();
if( targetLine < currentLine )
state->extendLiveRanges( targetLine, currentLine );
break;
}

state->storeBranch( &*target );

state->pushTraces( &*curr, false );
state->pushTraces( &after, false );
state->pushTraces( &*target, true );

curr = target;
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ set(OPENVCL_TEST_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_instruction_info_dump.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_pairing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_literal_register_conflict.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_trailing_branch_ranges.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_flag_latency.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_emit_source.cpp
${CMAKE_CURRENT_SOURCE_DIR}/integration/test_continuation_lifetime.cpp
Expand Down
65 changes: 65 additions & 0 deletions test/integration/test_trailing_branch_ranges.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Regression test: a branch that ends the program keeps live ranges inside
// the program.
//
// The register allocator ends a path's stretch of the program at the token
// after a branch. When the branch was the program's last token, as in
// ps2gl's programs that loop back with `b` and have no --exit block, that
// token was the end of the token list: dereferencing it read whatever lay
// past the list, and the ranges of values live across the branch ended at
// that number.

#include "test_harness.h"
#include "openvcl_runner.h"

#include <cstdlib>
#include <string>
#include <vector>

namespace
{
// fA and iN are live across the b on the last line, line 11.
const char* kTrailingBranch =
"\t.init_vf_all\n"
"\t.init_vi_all\n"
"\t.syntax new\n"
"\t--enter\n"
"\t--endenter\n"
"\tlq fA, 0(vi00)\n"
"\tiaddiu iN, vi00, 1\n"
"lLoop:\n"
"\tsq fA, 1(iN)\n"
"\tiaddiu iN, iN, 1\n"
"\tb lLoop\n";

const unsigned long kLastLine = 11;

// The ends of the [start-stop] ranges --show-reg-alloc prints.
std::vector<unsigned long> rangeEnds(const std::string& report)
{
std::vector<unsigned long> result;
std::string::size_type open = report.find('[');
while (open != std::string::npos)
{
const std::string::size_type dash = report.find('-', open);
const std::string::size_type close = report.find(']', open);
if (dash != std::string::npos && close != std::string::npos && dash < close
&& report.find_first_not_of("0123456789", open + 1) == dash)
result.push_back(std::strtoul(report.c_str() + dash + 1, NULL, 10));
open = report.find('[', open + 1);
}
return result;
}
}

TEST_CASE("openvcl: values live across a branch that ends the program keep ranges inside it")
{
std::vector<std::string> args;
args.push_back("--show-reg-alloc");
::test::RunResult result = ::test::run_openvcl(args, kTrailingBranch);
REQUIRE(result.exit_code == 0);

const std::vector<unsigned long> ends = rangeEnds(result.stderr_data);
REQUIRE(!ends.empty());
for (unsigned int i = 0; i < ends.size(); ++i)
CHECK(ends[i] <= kLastLine);
}
Loading