diff --git a/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp b/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp index c6a34f2025fbbfc0f134ad18b2cfcfc696f19ec0..b2acc2caa86069ad5282ace5bbe5b6a8d5f2cd4d 100644 --- a/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp +++ b/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp @@ -526,7 +526,9 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs, && "verifyUses() requires outerInputs for loops"); if (region.contains.empty()) { // A region with code in it, so actually check the operands used - std::set<Instruction*> outsideValues; + // Track the values from outside the region used in it (and track in the + // bool whether the value is used by the loop condition for parallel loops) + std::set<std::pair<Instruction*, bool>> outsideValues; Instruction* start = region.start->getNextNonDebugInstruction(); Instruction* end = region.end; @@ -576,7 +578,7 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs, // side-effect free and don't touch memory, because these are the // only ones that are safe to then rematerialize in the task // (possibly in multiple tasks or multiple iterations) - outsideValues.insert(inst); + outsideValues.insert(std::make_pair(inst, isLoopCond)); } else { errors = true; reportErrorOnInst("Cannot use value defined outside of this " @@ -602,14 +604,17 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs, } // Convert to a vector so we can add elements to it as we traverse - std::vector<Instruction*> values(outsideValues.begin(), outsideValues.end()); + std::vector<std::pair<Instruction*, bool>> + values(outsideValues.begin(), outsideValues.end()); // We now process all of the operands that are values from instructions // outside of the region or that otherwise come from outside of the region. for (unsigned int i = 0; i < values.size(); i++) { - Instruction* inst = values[i]; + Instruction* inst = values[i].first; + bool isLoopCond = values[i].second; for (Value* op : inst->operands()) { - if (inputs.find(op) == inputs.end()) { + if (inputs.find(op) == inputs.end() + && (!isLoopCond || outerInputs->find(op) == outerInputs->end())) { Instruction* ins = dyn_cast<Instruction>(op); Constant* const_ = dyn_cast<Constant>(op); BasicBlock* block = dyn_cast<BasicBlock>(op); @@ -620,10 +625,11 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs, && !ins->mayReadOrWriteMemory()) { // Add to the list to verify, to make sure that all operands these // instructions depend on satisfy these properties - auto f = outsideValues.find(ins); + std::pair<Instruction*, bool> pair = std::make_pair(ins, isLoopCond); + auto f = outsideValues.find(pair); if (f == outsideValues.end()) { - outsideValues.insert(ins); - values.push_back(ins); + outsideValues.insert(pair); + values.push_back(pair); } } else { errors = true; diff --git a/hpvm/projects/hetero-c++/test/integration/src/test.cc b/hpvm/projects/hetero-c++/test/integration/src/test.cc new file mode 100644 index 0000000000000000000000000000000000000000..b59a5e8fe087a8f0ec7adce7489e23bf90828c18 --- /dev/null +++ b/hpvm/projects/hetero-c++/test/integration/src/test.cc @@ -0,0 +1,28 @@ +#include <stdlib.h> +#include <stdio.h> +#include "heterocc.h" + +void dummy(size_t bytes_prod, size_t matrix_dim) { + void* Section = __hetero_section_begin(); + + int loop_size = matrix_dim / sizeof(int); + + for(int i = 0; i < loop_size; ++i){ + __hetero_parallel_loop( + /* Number of parallel enclosing loops */ 1, + /* Number of Input Buffer Pairs */ 1, bytes_prod, + /* Number of Output Buffer Pairs */ 1, bytes_prod); + printf("success"); + + } + + __hetero_section_end(Section); +} + +int main() { + size_t x = 3, y = 7; + auto l = __hetero_launch((void*)dummy, 2, x, y, 0); + __hetero_wait(l); + + return 0; +}