Skip to content
Closed
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
16 changes: 16 additions & 0 deletions backend/cmake/CHPLX_Compile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,22 @@ function(chplx_compile_project name)
set(generator_toolset -T ${CMAKE_GENERATOR_TOOLSET})
endif()

if(NOT fmt_DIR AND CHPLX_WITH_TESTS)
if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/cmake/fmt")
message(STATUS "Using fmt from ${CMAKE_INSTALL_PREFIX}/lib/cmake/fmt")
set(fmt_DIR "${CMAKE_INSTALL_PREFIX}/lib/cmake/fmt" CACHE PATH
"Path to fmt CMake configuration files")
endif()
endif()

if(NOT HPX_DIR AND CHPLX_WITH_TESTS)
if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/cmake/HPX")
message(STATUS "Using HPX from ${CMAKE_INSTALL_PREFIX}/lib/cmake/HPX")
set(HPX_DIR "${CMAKE_INSTALL_PREFIX}/lib/cmake/HPX" CACHE PATH
"Path to HPX CMake configuration files")
endif()
endif()

add_custom_command(
COMMAND ${CMAKE_COMMAND} . -B ./build
-G ${CMAKE_GENERATOR} ${generator_toolset}
Expand Down
2 changes: 2 additions & 0 deletions backend/include/hpx/programtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ struct ForLoopExpression : public ScopeExpression {
std::vector<Statement> statements;
std::string chplLine;

bool isArrayInitForLoop = false;

void emit(std::ostream & os) const;
};

Expand Down
4 changes: 4 additions & 0 deletions backend/include/hpx/programtreebuildingvisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <unordered_map>
#include <variant>
#include <vector>
#include <queue>
#include <map>

using namespace chplx::ast::hpx;
using namespace chpl;
Expand All @@ -50,6 +52,8 @@ struct ProgramTreeBuildingVisitor {

std::vector< std::vector<Statement> * > curStmts;
std::optional<uast::AstTag> prevTag;
std::deque<std::optional<Symbol>> pendingArrayForLoopSymbols;
std::map<std::string, bool> pendingArrayForLoopSymbolsMap;

static std::unordered_map<std::string, int> operatorEncoder;
};
Expand Down
3 changes: 3 additions & 0 deletions backend/include/hpx/symboltypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ struct array_kind : public funcbase_kind {
struct func_kind : public funcbase_kind {
bool is_iter;
bool is_lambda;
bool isArrayInitForLoop = false;
std::string arrayIdentifier = ""; // used in array init for-loops
std::optional<Symbol> arraySym;
};

struct tuple_kind : public funcbase_kind {
Expand Down
145 changes: 135 additions & 10 deletions backend/src/programtreebuildingvisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,39 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {
std::string identifier{dynamic_cast<Identifier const*>(ast)->name().c_str()};
std::optional<Symbol> varsym =
symbolTable.find(symbolTableRef->id, identifier);

if (fle->isArrayInitForLoop)
{
auto arrayVarsym = pendingArrayForLoopSymbols.front();
pendingArrayForLoopSymbols.pop_front();
auto arrayIdentifier = arrayVarsym->identifier;

auto varsymInsideForLoop = arrayVarsym;
std::string iteratorName = fle->iterator.identifier;
auto arrayIdentifierForLoopExpression =
arrayIdentifier + "(" + iteratorName + ")";
std::vector<Statement>* cStmts = curStmts.back();
varsymInsideForLoop->kind = std::make_shared<func_kind>(func_kind{
{symbolTable.symbolTableRef->id, {}, {}, {}}, true, false});

cStmts->emplace_back(std::make_shared<BinaryOpExpression>(
BinaryOpExpression{{{symbolTableRef->id}, "=", ast}, {}}));
auto& bo =
std::get<std::shared_ptr<BinaryOpExpression>>(cStmts->back());

bo->statements.emplace_back(

VariableExpression{std::make_shared<Symbol>(Symbol{
varsymInsideForLoop->kind,
arrayIdentifierForLoopExpression, // This is "arr(i)"
{}, -1, false, symbolTableRef->id})});

bo->statements.emplace_back(
VariableExpression{std::make_shared<Symbol>(*varsym)});

return true;
}

if(varsym) {
if(fle->indexSet.size() < 2) {
fle->indexSet.emplace_back(VariableExpression{std::make_shared<Symbol>(*varsym)});
Expand Down Expand Up @@ -1187,21 +1220,65 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {
std::shared_ptr<ForLoopExpression> & fle =
std::get<std::shared_ptr<ForLoopExpression>>(curStmts[curStmts.size()-2]->back());

if(fle->indexSet.size() < 2) {
fle->indexSet.emplace_back(
std::make_shared<BinaryOpExpression>(BinaryOpExpression{
{{symbolTableRef->id}, identifier, ast}, {}
})
std::string arrayIdentifier = "";
std::optional<Symbol> arrayVarsym{};

// Search in parent scope for array variables
if(!pendingArrayForLoopSymbols.empty() && fle->isArrayInitForLoop) {
arrayVarsym = pendingArrayForLoopSymbols.front();
pendingArrayForLoopSymbols.pop_front();
arrayIdentifier = arrayVarsym->identifier;

auto varsymInsideForLoop = arrayVarsym;
std::string iteratorName = fle->iterator.identifier;
auto arrayIdentifierForLoopExpression = arrayIdentifier + "(" + iteratorName + ")";
std::vector<Statement> * cStmts = curStmts.back();
varsymInsideForLoop->kind = std::make_shared<func_kind>(func_kind{{
symbolTable.symbolTableRef->id, {}, {}, {}}, true, false});
cStmts->emplace_back(
std::make_shared<BinaryOpExpression>(BinaryOpExpression{
{{symbolTableRef->id}, "=", ast}, {}
})
);
auto & bo = std::get<std::shared_ptr<BinaryOpExpression>>(cStmts->back());


bo->statements.emplace_back(

VariableExpression{std::make_shared<Symbol>(Symbol{
varsymInsideForLoop->kind,
arrayIdentifierForLoopExpression, // This is "arr(i)"
{}, -1, false, symbolTableRef->id
})}
);

bo->statements.emplace_back(
std::make_shared<BinaryOpExpression>(
BinaryOpExpression{ {{symbolTableRef->id}, identifier, ast}, {} }
)
);

auto & rhsOp = std::get<std::shared_ptr<BinaryOpExpression>>(bo->statements.back());
curStmts.push_back(&(rhsOp->statements));
}
else {
cStmts->emplace_back(


if(fle->indexSet.size() < 2) {
fle->indexSet.emplace_back(
std::make_shared<BinaryOpExpression>(BinaryOpExpression{
{{symbolTableRef->id}, identifier, ast}, {}
})
);
auto & nbo = std::get<std::shared_ptr<BinaryOpExpression>>(cStmts->back());
curStmts.push_back(&(nbo->statements));
}else{
if(!arrayVarsym) {
cStmts->emplace_back(
std::make_shared<BinaryOpExpression>(BinaryOpExpression{
{{symbolTableRef->id}, identifier, ast}, {}
})
);
auto & nbo = std::get<std::shared_ptr<BinaryOpExpression>>(cStmts->back());
curStmts.push_back(&(nbo->statements));
}
}
}
else if(1 < curStmts.size() && curStmts[curStmts.size()-2]->size() && std::holds_alternative<std::shared_ptr<ForallLoopExpression>>(curStmts[curStmts.size()-2]->back())) {
Expand Down Expand Up @@ -1335,6 +1412,7 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {
std::string identifier =
std::string{dynamic_cast<NamedDecl const*>(ast)->name().c_str()};
std::optional<Symbol> varsym{};
std::optional<Symbol> varsymInsideForLoop{};
symbolTable.find(symbolTableRef->id, identifier, varsym);
bool stmt = true;

Expand All @@ -1344,6 +1422,46 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {

fl->iterator = *varsym;
stmt = false;

if (fl->isArrayInitForLoop)
{
// This is the iterator variable in an array init for-loop
// We need to find the target array variable from the parent scope
// Look for array variable in the parent scope that's being initialized
// Search in parent scope for array variables
auto parentScopeId = symbolTable.parentSymbolTableId;
std::optional<std::pair<std::map<std::string, Symbol>::iterator,
std::map<std::string, Symbol>::iterator>>
allSymbols = symbolTable.findPrefix(parentScopeId, "");
if (allSymbols.has_value())
{
for (auto it = allSymbols->first; it != allSymbols->second;
++it)
{
if (std::holds_alternative<std::shared_ptr<func_kind>>(
it->second.kind))
{
auto func_sym = std::get<std::shared_ptr<func_kind>>(
it->second.kind);
if (func_sym->isArrayInitForLoop)
{
const auto& candidate = func_sym->arraySym;
const auto& candidateArrIdentifier = func_sym->arrayIdentifier;

if (pendingArrayForLoopSymbolsMap.find(candidateArrIdentifier) !=
pendingArrayForLoopSymbolsMap.end())
{
// Already added this symbol
continue;
}
pendingArrayForLoopSymbolsMap[candidateArrIdentifier] = true;

pendingArrayForLoopSymbols.push_back(candidate);
}
}
}
}
}
}
else if (1 < curStmts.size() && std::holds_alternative<std::shared_ptr<ForallLoopExpression>>( curStmts[curStmts.size()-2]->back() ) ) {
std::shared_ptr<ForallLoopExpression> & fl =
Expand Down Expand Up @@ -1596,6 +1714,13 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {
std::string identifier{"for" + emitChapelLine(ast)};
std::optional<Symbol> varsym =
symbolTable.find(symbolTableRef->id, identifier);
bool isArrayInitForLoop = false;

if(!varsym) {
identifier = "array_init_for" + emitChapelLine(ast);
varsym = symbolTable.find(symbolTableRef->id, identifier);
if(varsym.has_value()) isArrayInitForLoop = true;
}

if(varsym.has_value() && std::holds_alternative<std::shared_ptr<func_kind>>(varsym->kind)) {
std::vector<Statement> * cStmts = curStmts.back();
Expand All @@ -1605,7 +1730,7 @@ bool ProgramTreeBuildingVisitor::enter(const uast::AstNode * ast) {

cStmts->emplace_back(
std::make_shared<ForLoopExpression>(
ForLoopExpression{{{fk->lutId}, ast, {}}, *varsym, {}, {}, {}, emitChapelLine(ast)}
ForLoopExpression{{{fk->lutId}, ast, {}}, *varsym, {}, {}, {}, emitChapelLine(ast),isArrayInitForLoop}
));

auto & fndecl = std::get<std::shared_ptr<ForLoopExpression>>(cStmts->back());
Expand Down
93 changes: 68 additions & 25 deletions backend/src/symbolbuildingvisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,32 +1317,75 @@ std::cout << "BLOCK HERE" << std::endl;
{
// symbol.scopePtr = the scope where the function is defined (equivalent to a lutId)
//
symstack.emplace_back(
Symbol{{
std::make_shared<func_kind>(func_kind{{
symbolTable.symbolTableRef->id, {}, {}, {}}}),
std::string{"for" + emitChapelLine(ast)},
{}, -1, false, symbolTable.symbolTableRef->id
}});

std::shared_ptr<SymbolTable::SymbolTableNode> prevSymbolTableRef = symbolTable.symbolTableRef;
const std::size_t parScope = symbolTable.symbolTableRef->id;

symbolTable.pushScope();
sym.reset();
sym = symstack.back();

std::shared_ptr<func_kind> & fk =
std::get<std::shared_ptr<func_kind>>(sym->get().kind);

fk->symbolTableSignature = sym->get().identifier;
// func_kind.lutId = the scope where the function's symboltable references
//
fk->lutId = symbolTable.symbolTableRef->id;
bool isArrayInitExpr = symnode // we have a current AST node
&& symnode->tag() == asttags::Variable // that is a `var …` decl
&& std::holds_alternative<std::shared_ptr<array_kind>>(
sym->get().kind); // whose kind is still array

if (std::holds_alternative<std::shared_ptr<array_kind>>(
sym->get().kind) &&
isArrayInitExpr)
{
// This is a for-loop expression used to initialize an array
std::shared_ptr<array_kind>& arrk =
std::get<std::shared_ptr<array_kind>>(sym->get().kind);

// Mark this as an array initialization for-loop
symstack.emplace_back(
Symbol{{std::make_shared<func_kind>(func_kind{
{symbolTable.symbolTableRef->id, {}, {}, {}}, false,
false, true, sym->get().identifier, sym}),
std::string{"array_init_for" + emitChapelLine(ast)}, {}, -1,
false, symbolTable.symbolTableRef->id}});

std::shared_ptr<SymbolTable::SymbolTableNode> prevSymbolTableRef =
symbolTable.symbolTableRef;
const std::size_t parScope = symbolTable.symbolTableRef->id;
symbolTable.pushScope();

auto prevSym = sym;
sym.reset();
sym = symstack.back();

symbolTable.parentSymbolTableId = parScope;
symbolTable.symbolTableRef->parent = prevSymbolTableRef;
symnode = const_cast<uast::AstNode*>(ast);
std::shared_ptr<func_kind>& fk =
std::get<std::shared_ptr<func_kind>>(sym->get().kind);

fk->symbolTableSignature = sym->get().identifier;
fk->lutId = symbolTable.symbolTableRef->id;

symbolTable.parentSymbolTableId = parScope;
symbolTable.symbolTableRef->parent = prevSymbolTableRef;

symnode = const_cast<uast::AstNode*>(ast);
}
else{
symstack.emplace_back(
Symbol{{
std::make_shared<func_kind>(func_kind{{
symbolTable.symbolTableRef->id, {}, {}, {}}}),
std::string{"for" + emitChapelLine(ast)},
{}, -1, false, symbolTable.symbolTableRef->id
}});

std::shared_ptr<SymbolTable::SymbolTableNode> prevSymbolTableRef = symbolTable.symbolTableRef;
const std::size_t parScope = symbolTable.symbolTableRef->id;

symbolTable.pushScope();
sym.reset();
sym = symstack.back();

std::shared_ptr<func_kind> & fk =
std::get<std::shared_ptr<func_kind>>(sym->get().kind);

fk->symbolTableSignature = sym->get().identifier;
// func_kind.lutId = the scope where the function's symboltable references
//
fk->lutId = symbolTable.symbolTableRef->id;

symbolTable.parentSymbolTableId = parScope;
symbolTable.symbolTableRef->parent = prevSymbolTableRef;
symnode = const_cast<uast::AstNode*>(ast);
}
}
break;
case asttags::Forall:
Expand Down
18 changes: 18 additions & 0 deletions backend/test/forall.chpl
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,21 @@ coforall tid in 0..2 do

for i in 0..2 do
inlinecxx("std::cout << {} << std::endl;", C[i]);


var D : [0..2] int = for i in 0..2 do
i;

var E : [0..2] int = for i in 0..2 do
i+1;

var F : [0..2] int = for i in 0..2 do
i+1 + i+1;

var G : [0..2] int;

for i in 0..2 do
G[i] = i+1 + i+1;

var H : [0..2] int = for j in 0..2 do
j+1 + j+1;
Loading
Loading