#include #include #include #include #include #include #include "range_structures.h" #include "region.h" #include "../Utils/SgUtils.h" using namespace std; static bool isParentStmt(SgStatement* stmt, SgStatement* parent) { for (; stmt; stmt = stmt->controlParent()) if (stmt == parent) return true; return false; } /*returns head block and loop*/ pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) { unordered_set block_loop; SAPFOR::BasicBlock* head_block = nullptr; auto loop_operator = loop->loop->GetOriginal(); for (const auto& block : blocks) { if (!block || (block->getInstructions().size() == 0)) continue; SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator(); SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator(); if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator)) { block_loop.insert(block); if ((!head_block) && (first == loop_operator) && (last == loop_operator) && (block->getInstructions().size() == 2) && (block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF)) { head_block = block; } } } return { head_block, block_loop }; } static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { string index = loop->loopSymbol; loopForIndex[index] = loop; for (const auto& childLoop : loop->children) BuildLoopIndex(loopForIndex, childLoop); } static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map& loopForIndex) { unordered_set args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; for (int i = pos - 1; i >= 0; i--) { SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult(); if (res && args.find(res) != args.end()) { SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1(); SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2(); if (arg1) { string name = arg1->getValue(); int idx = name.find('%'); if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) return name.substr(idx + 1); else args.insert(arg1); } if (arg2) { string name = arg2->getValue(); int idx = name.find('%'); if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) return name.substr(idx + 1); else args.insert(arg2); } } } return ""; } static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) { auto instructions = block->getInstructions(); map loopForIndex; BuildLoopIndex(loopForIndex, loop); for (int i = 0; i < instructions.size(); i++) { auto instruction = instructions[i]; if (!instruction->getInstruction()->getArg1()) continue; auto operation = instruction->getInstruction()->getOperation(); auto type = instruction->getInstruction()->getArg1()->getType(); if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY) { vector index_vars; vector refPos; string array_name; if (operation == SAPFOR::CFG_OP::STORE) array_name = instruction->getInstruction()->getArg1()->getValue(); else array_name = instruction->getInstruction()->getArg2()->getValue(); int j = i - 1; while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) { index_vars.push_back(instructions[j]->getInstruction()->getArg1()); refPos.push_back(j); j--; } /*to choose correct dimension*/ int n = index_vars.size(); vector accessPoint(n); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); vector> coefsForDims; for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) { const vector& coefs = getAttributes(ref->subscript(i), set{ INT_VAL }); if (coefs.size() == 1) { const pair coef(coefs[0][0], coefs[0][1]); coefsForDims.push_back(coef); } } while (!index_vars.empty()) { auto var = index_vars.back(); int currentVarPos = refPos.back(); pair currentCoefs = coefsForDims.back(); ArrayDimension current_dim; if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) current_dim = { stoul(var->getValue()), 1, 1 }; else { string name, full_name = var->getValue(); int pos = full_name.find('%'); LoopGraph* currentLoop; if (pos != -1) { name = full_name.substr(pos + 1); if (loopForIndex.find(name) != loopForIndex.end()) currentLoop = loopForIndex[name]; else return -1; } else { name = FindIndexName(currentVarPos, block, loopForIndex); if (name == "") return -1; if (loopForIndex.find(name) != loopForIndex.end()) currentLoop = loopForIndex[name]; else return -1; } uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second; uint64_t step = currentCoefs.first; current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters }; } accessPoint[n - index_vars.size()] = current_dim; index_vars.pop_back(); refPos.pop_back(); coefsForDims.pop_back(); } if (operation == SAPFOR::CFG_OP::STORE) def[array_name].Insert(accessPoint); else use[array_name].Insert(accessPoint); } } return 0; } static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) { for (SAPFOR::BasicBlock* block : blockSet) { for (SAPFOR::BasicBlock* nextBlock : block->getNext()) if (bbToRegion.find(nextBlock) != bbToRegion.end()) bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]); for (SAPFOR::BasicBlock* prevBlock : block->getPrev()) if (bbToRegion.find(prevBlock) != bbToRegion.end()) bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]); } } static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, const unordered_map& bbToRegion) { Region* region = new Region; auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); if (bbToRegion.find(header) != bbToRegion.end()) region->setHeader(bbToRegion.at(header)); else return NULL; for (SAPFOR::BasicBlock* block : blockSet) if (bbToRegion.find(block) != bbToRegion.end()) region->addBasickBlocks(bbToRegion.at(block)); for (LoopGraph* childLoop : loop->children) region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); cout << header << endl; return region; } Region::Region(LoopGraph* loop, const vector& Blocks) { auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); unordered_map bbToRegion; for (auto poiner : blockSet) { bbToRegion[poiner] = new Region(*poiner); this->basickBlocks.insert(bbToRegion[poiner]); GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use); } this->header = bbToRegion[header]; SetConnections(bbToRegion, blockSet); //create subRegions for (LoopGraph* childLoop : loop->children) subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); }