void TempScopInfo::buildLoopBounds(TempScop &Scop) { Region &R = Scop.getMaxRegion(); unsigned MaxLoopDepth = 0; for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E; ++I) { Loop *L = LI->getLoopFor(I->getNodeAs<BasicBlock>()); if (!L || !R.contains(L)) continue; if (LoopBounds.find(L) != LoopBounds.end()) continue; LoopBounds[L] = SCEVAffFunc(SCEVAffFunc::Eq); const SCEV *LoopCount = SE->getBackedgeTakenCount(L); buildAffineFunction(LoopCount, LoopBounds[L], Scop.getMaxRegion(), Scop.getParamSet()); Loop *OL = R.outermostLoopInRegion(L); unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1; if (LoopDepth > MaxLoopDepth) MaxLoopDepth = LoopDepth; } Scop.MaxLoopDepth = MaxLoopDepth; }
//===----------------------------------------------------------------------===// /// Scop class implement Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution) : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), MaxLoopDepth(tempScop.getMaxLoopDepth()) { isl_ctx *ctx = isl_ctx_alloc(); ParamSetType &Params = tempScop.getParamSet(); Parameters.insert(Parameters.begin(), Params.begin(), Params.end()); isl_dim *dim = isl_dim_set_alloc(ctx, getNumParams(), 0); // TODO: Insert relations between parameters. // TODO: Insert constraints on parameters. Context = isl_set_universe (dim); SmallVector<Loop*, 8> NestLoops; SmallVector<unsigned, 8> Scatter; Scatter.assign(MaxLoopDepth + 1, 0); // Build the iteration domain, access functions and scattering functions // traversing the region tree. buildScop(tempScop, getRegion(), NestLoops, Scatter, LI); Stmts.push_back(new ScopStmt(*this, Scatter)); assert(NestLoops.empty() && "NestLoops not empty at top level!"); }
void ScopStmt::addConditionsToDomain(TempScop &tempScop, const Region &CurRegion) { isl_dim *dim = isl_set_get_dim(Domain); const Region *TopR = tempScop.getMaxRegion().getParent(), *CurR = &CurRegion; const BasicBlock *CurEntry = BB; // Build BB condition constrains, by traveling up the region tree. do { assert(CurR && "We exceed the top region?"); // Skip when multiple regions share the same entry. if (CurEntry != CurR->getEntry()) { if (const BBCond *Cnd = tempScop.getBBCond(CurEntry)) for (BBCond::const_iterator I = Cnd->begin(), E = Cnd->end(); I != E; ++I) { isl_set *c = toConditionSet(*I, dim); Domain = isl_set_intersect(Domain, c); } } CurEntry = CurR->getEntry(); CurR = CurR->getParent(); } while (TopR != CurR); isl_dim_free(dim); }
void TempScopInfo::buildAffineCondition(Value &V, bool inverted, Comparison **Comp, TempScop &Scop) const { Region &R = Scop.getMaxRegion(); ParamSetType &Params = Scop.getParamSet(); if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) { // If this is always true condition, we will create 1 >= 0, // otherwise we will create 1 == 0. SCEVAffFunc *AffLHS = new SCEVAffFunc(SE->getConstant(C->getType(), 0), SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(SE->getConstant(C->getType(), 1), SCEVAffFunc::Eq, R, Params, LI, SE); if (C->isOne() == inverted) *Comp = new Comparison(AffRHS, AffLHS, ICmpInst::ICMP_NE); else *Comp = new Comparison(AffLHS, AffLHS, ICmpInst::ICMP_EQ); return; } ICmpInst *ICmp = dyn_cast<ICmpInst>(&V); assert(ICmp && "Only ICmpInst of constant as condition supported!"); const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)), *RHS = SE->getSCEV(ICmp->getOperand(1)); ICmpInst::Predicate Pred = ICmp->getPredicate(); // Invert the predicate if needed. if (inverted) Pred = ICmpInst::getInversePredicate(Pred); SCEVAffFunc *AffLHS = new SCEVAffFunc(LHS, SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(RHS, SCEVAffFunc::Eq, R, Params, LI, SE); switch (Pred) { case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: // TODO: At the moment we need to see everything as signed. This is an // correctness issue that needs to be solved. //AffLHS->setUnsigned(); //AffRHS->setUnsigned(); break; default: break; } *Comp = new Comparison(AffLHS, AffRHS, Pred); }
ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, BasicBlock &bb, SmallVectorImpl<Loop*> &NestLoops, SmallVectorImpl<unsigned> &Scatter) : Parent(parent), BB(&bb), IVS(NestLoops.size()) { // Setup the induction variables. for (unsigned i = 0, e = NestLoops.size(); i < e; ++i) { PHINode *PN = NestLoops[i]->getCanonicalInductionVariable(); assert(PN && "Non canonical IV in Scop!"); IVS[i] = PN; } raw_string_ostream OS(BaseName); WriteAsOperand(OS, &bb, false); BaseName = OS.str(); // Remove the % in the name. This is not supported by isl. BaseName.erase(0, 1); makeIslCompatible(BaseName); BaseName = "Stmt_" + BaseName; buildIterationDomain(tempScop, CurRegion); buildScattering(Scatter); buildAccesses(tempScop, CurRegion); IsReduction = tempScop.is_Reduction(*BB); }
void ScopStmt::buildIterationDomainFromLoops(TempScop &tempScop) { isl_dim *dim = isl_dim_set_alloc(Parent.getCtx(), getNumParams(), getNumIterators()); dim = isl_dim_set_tuple_name(dim, isl_dim_set, getBaseName()); Domain = isl_set_universe(isl_dim_copy(dim)); isl_int v; isl_int_init(v); for (int i = 0, e = getNumIterators(); i != e; ++i) { // Lower bound: IV >= 0. isl_basic_set *bset = isl_basic_set_universe(isl_dim_copy(dim)); isl_constraint *c = isl_inequality_alloc(isl_dim_copy(dim)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, i, v); bset = isl_basic_set_add_constraint(bset, c); Domain = isl_set_intersect(Domain, isl_set_from_basic_set(bset)); // Upper bound: IV <= NumberOfIterations. const Loop *L = getSCEVForDimension(i)->getLoop(); const SCEVAffFunc &UpperBound = tempScop.getLoopBound(L); isl_set *UpperBoundSet = toUpperLoopBound(UpperBound, isl_dim_copy(dim), i); Domain = isl_set_intersect(Domain, UpperBoundSet); } isl_int_clear(v); }
void TempScopInfo::buildLoopBounds(TempScop &Scop) { Region &R = Scop.getMaxRegion(); unsigned MaxLoopDepth = 0; for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E; ++I) { Loop *L = LI->getLoopFor(*I); if (!L || !R.contains(L)) continue; if (LoopBounds.find(L) != LoopBounds.end()) continue; const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L); LoopBounds[L] = BackedgeTakenCount; Loop *OL = R.outermostLoopInRegion(L); unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1; if (LoopDepth > MaxLoopDepth) MaxLoopDepth = LoopDepth; } Scop.MaxLoopDepth = MaxLoopDepth; }
void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) { const AccFuncSetType *AccFuncs = tempScop.getAccessFunctions(BB); for (AccFuncSetType::const_iterator I = AccFuncs->begin(), E = AccFuncs->end(); I != E; ++I) { MemAccs.push_back(new MemoryAccess(I->first, this)); InstructionToAccess[I->second] = MemAccs.back(); } }
TempScop *TempScopInfo::buildTempScop(Region &R) { TempScop *TScop = new TempScop(R, LoopBounds, BBConds, AccFuncMap); for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E; ++I) { BasicBlock *BB = I->getNodeAs<BasicBlock>(); buildAccessFunctions(R, TScop->getParamSet(), *BB); buildCondition(BB, R.getEntry(), *TScop); if (isReduction(*BB)) TScop->Reductions.insert(BB); } buildLoopBounds(*TScop); // Build the MayAliasSets. TScop->MayASInfo->buildMayAliasSets(*TScop, *AA); return TScop; }
bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) { LoopInfo &LI = getAnalysis<LoopInfo>(); ScalarEvolution &SE = getAnalysis<ScalarEvolution>(); TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R); // This region is no Scop. if (!tempScop) { scop = 0; return false; } // Statistics. ++ScopFound; if (tempScop->getMaxLoopDepth() > 0) ++RichScopFound; scop = new Scop(*tempScop, LI, SE); return false; }
Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution, isl_ctx *Context) : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), MaxLoopDepth(tempScop.getMaxLoopDepth()) { IslCtx = Context; buildContext(); SmallVector<Loop *, 8> NestLoops; SmallVector<unsigned, 8> Scatter; Scatter.assign(MaxLoopDepth + 1, 0); // Build the iteration domain, access functions and scattering functions // traversing the region tree. buildScop(tempScop, getRegion(), NestLoops, Scatter, LI); realignParams(); addParameterBounds(); assert(NestLoops.empty() && "NestLoops not empty at top level!"); }
void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) { const AccFuncSetType *AccFuncs = tempScop.getAccessFunctions(BB); for (AccFuncSetType::const_iterator I = AccFuncs->begin(), E = AccFuncs->end(); I != E; ++I) { MemAccs.push_back(new MemoryAccess(I->first, I->second, this)); assert(!InstructionToAccess.count(I->second) && "Unexpected 1-to-N mapping on instruction to access map!"); InstructionToAccess[I->second] = MemAccs.back(); } }
bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) { if (tempScop.getAccessFunctions(BB)) return false; return true; }