// Print the cluster of the subregions. This groups the single basic blocks // and adds a different background color for each group. static void printRegionCluster(const Region &R, GraphWriter<RegionInfo *> &GW, unsigned depth = 0) { raw_ostream &O = GW.getOStream(); O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R) << " {\n"; O.indent(2 * (depth + 1)) << "label = \"\";\n"; if (!onlySimpleRegions || R.isSimple()) { O.indent(2 * (depth + 1)) << "style = filled;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 1) << "\n"; } else { O.indent(2 * (depth + 1)) << "style = solid;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 2) << "\n"; } for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) printRegionCluster(**RI, GW, depth + 1); const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo()); for (auto *BB : R.blocks()) if (RI.getRegionFor(BB) == &R) O.indent(2 * (depth + 1)) << "Node" << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB)) << ";\n"; O.indent(2 * depth) << "}\n"; }
void TempScopInfo::buildAccessFunctions(Region &R, Region &SR) { if (SD->isNonAffineSubRegion(&SR, &R)) { for (BasicBlock *BB : SR.blocks()) buildAccessFunctions(R, *BB, &SR); return; } for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I) if (I->isSubRegion()) buildAccessFunctions(R, *I->getNodeAs<Region>()); else buildAccessFunctions(R, *I->getNodeAs<BasicBlock>()); }
bool ScopDetection::isInvariant(const Value &Val, const Region &Reg) const { // A reference to function argument or constant value is invariant. if (isa<Argument>(Val) || isa<Constant>(Val)) return true; const Instruction *I = dyn_cast<Instruction>(&Val); if (!I) return false; if (!Reg.contains(I)) return true; if (I->mayHaveSideEffects()) return false; // When Val is a Phi node, it is likely not invariant. We do not check whether // Phi nodes are actually invariant, we assume that Phi nodes are usually not // invariant. Recursively checking the operators of Phi nodes would lead to // infinite recursion. if (isa<PHINode>(*I)) return false; for (const Use &Operand : I->operands()) if (!isInvariant(*Operand, Reg)) return false; // When the instruction is a load instruction, check that no write to memory // in the region aliases with the load. if (const LoadInst *LI = dyn_cast<LoadInst>(I)) { AliasAnalysis::Location Loc = AA->getLocation(LI); const Region::const_block_iterator BE = Reg.block_end(); // Check if any basic block in the region can modify the location pointed to // by 'Loc'. If so, 'Val' is (likely) not invariant in the region. for (const BasicBlock *BB : Reg.blocks()) if (AA->canBasicBlockModify(*BB, Loc)) return false; } return true; }