void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, Region *NonAffineSubRegion) { AccFuncSetType Functions; Loop *L = LI->getLoopFor(&BB); // The set of loops contained in non-affine subregions that are part of R. const ScopDetection::BoxedLoopsSetTy *BoxedLoops = SD->getBoxedLoops(&R); for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { Instruction *Inst = I; if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) Functions.push_back( std::make_pair(buildIRAccess(Inst, L, &R, BoxedLoops), Inst)); if (PHINode *PHI = dyn_cast<PHINode>(Inst)) buildPHIAccesses(PHI, R, Functions, NonAffineSubRegion); if (!isa<StoreInst>(Inst) && buildScalarDependences(Inst, &R, NonAffineSubRegion)) { // If the Instruction is used outside the statement, we need to build the // write access. IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true); Functions.push_back(std::make_pair(ScalarAccess, Inst)); } } if (Functions.empty()) return; AccFuncSetType &Accs = AccFuncMap[&BB]; Accs.insert(Accs.end(), Functions.begin(), Functions.end()); }
void TempScopInfo::buildAccessFunctions(Region &R, ParamSetType &Params, BasicBlock &BB) { AccFuncSetType Functions; for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { Instruction &Inst = *I; if (isa<LoadInst>(&Inst) || isa<StoreInst>(&Inst)) { // Create the SCEVAffFunc. if (LoadInst *ld = dyn_cast<LoadInst>(&Inst)) { unsigned size = TD->getTypeStoreSize(ld->getType()); Functions.push_back( std::make_pair(SCEVAffFunc(SCEVAffFunc::ReadMem, size), &Inst)); } else {//Else it must be a StoreInst. StoreInst *st = cast<StoreInst>(&Inst); unsigned size = TD->getTypeStoreSize(st->getValueOperand()->getType()); Functions.push_back( std::make_pair(SCEVAffFunc(SCEVAffFunc::WriteMem, size), &Inst)); } Value *Ptr = getPointerOperand(Inst); buildAffineFunction(SE->getSCEV(Ptr), Functions.back().first, R, Params); } } if (Functions.empty()) return; AccFuncSetType &Accs = AccFuncMap[&BB]; Accs.insert(Accs.end(), Functions.begin(), Functions.end()); }
void TempScopInfo::buildPHIAccesses(PHINode *PHI, Region &R, AccFuncSetType &Functions, Region *NonAffineSubRegion) { if (canSynthesize(PHI, LI, SE, &R)) return; // PHI nodes are modeled as if they had been demoted prior to the SCoP // detection. Hence, the PHI is a load of a new memory location in which the // incoming value was written at the end of the incoming basic block. bool Written = false; for (unsigned u = 0; u < PHI->getNumIncomingValues(); u++) { Value *Op = PHI->getIncomingValue(u); BasicBlock *OpBB = PHI->getIncomingBlock(u); if (!R.contains(OpBB)) continue; // Do not build scalar dependences inside a non-affine subregion. if (NonAffineSubRegion && NonAffineSubRegion->contains(OpBB)) continue; Instruction *OpI = dyn_cast<Instruction>(Op); if (OpI) { BasicBlock *OpIBB = OpI->getParent(); // As we pretend there is a use (or more precise a write) of OpI in OpBB // we have to insert a scalar dependence from the definition of OpI to // OpBB if the definition is not in OpBB. if (OpIBB != OpBB) { IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true); AccFuncMap[OpBB].push_back(std::make_pair(ScalarRead, PHI)); IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true); AccFuncMap[OpIBB].push_back(std::make_pair(ScalarWrite, OpI)); } } // If the operand is a constant, global or argument we need an access // instruction and just choose the PHI. if (!OpI) OpI = PHI; Written = true; IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true); AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI)); } if (Written) { IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true); Functions.push_back(std::make_pair(ScalarAccess, PHI)); } }
void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB) { AccFuncSetType Functions; for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { Instruction &Inst = *I; if (isa<LoadInst>(&Inst) || isa<StoreInst>(&Inst)) { unsigned Size; enum IRAccess::TypeKind Type; if (LoadInst *Load = dyn_cast<LoadInst>(&Inst)) { Size = TD->getTypeStoreSize(Load->getType()); Type = IRAccess::READ; } else { StoreInst *Store = cast<StoreInst>(&Inst); Size = TD->getTypeStoreSize(Store->getValueOperand()->getType()); Type = IRAccess::WRITE; } const SCEV *AccessFunction = SE->getSCEV(getPointerOperand(Inst)); const SCEVUnknown *BasePointer = dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction)); assert(BasePointer && "Could not find base pointer"); AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer); bool IsAffine = isAffineExpr(&R, AccessFunction, *SE, BasePointer->getValue()); Functions.push_back( std::make_pair(IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine), &Inst)); } } if (Functions.empty()) return; AccFuncSetType &Accs = AccFuncMap[&BB]; Accs.insert(Accs.end(), Functions.begin(), Functions.end()); }