//===----------------------------------------------------------------------===// /// 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 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; }
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); }
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; }