ScopInfo.cpp 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775
  1. //===- ScopInfo.cpp -------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Create a polyhedral description for a static control flow region.
  10. //
  11. // The pass creates a polyhedral description of the Scops detected by the Scop
  12. // detection derived from their LLVM-IR code.
  13. //
  14. // This representation is shared among several tools in the polyhedral
  15. // community, which are e.g. Cloog, Pluto, Loopo, Graphite.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #include "polly/ScopInfo.h"
  19. #include "polly/LinkAllPasses.h"
  20. #include "polly/Options.h"
  21. #include "polly/ScopBuilder.h"
  22. #include "polly/ScopDetection.h"
  23. #include "polly/Support/GICHelper.h"
  24. #include "polly/Support/ISLOStream.h"
  25. #include "polly/Support/ISLTools.h"
  26. #include "polly/Support/SCEVAffinator.h"
  27. #include "polly/Support/SCEVValidator.h"
  28. #include "polly/Support/ScopHelper.h"
  29. #include "llvm/ADT/APInt.h"
  30. #include "llvm/ADT/ArrayRef.h"
  31. #include "llvm/ADT/PostOrderIterator.h"
  32. #include "llvm/ADT/Sequence.h"
  33. #include "llvm/ADT/SmallPtrSet.h"
  34. #include "llvm/ADT/SmallSet.h"
  35. #include "llvm/ADT/Statistic.h"
  36. #include "llvm/Analysis/AliasAnalysis.h"
  37. #include "llvm/Analysis/AssumptionCache.h"
  38. #include "llvm/Analysis/Loads.h"
  39. #include "llvm/Analysis/LoopInfo.h"
  40. #include "llvm/Analysis/OptimizationRemarkEmitter.h"
  41. #include "llvm/Analysis/RegionInfo.h"
  42. #include "llvm/Analysis/RegionIterator.h"
  43. #include "llvm/Analysis/ScalarEvolution.h"
  44. #include "llvm/Analysis/ScalarEvolutionExpressions.h"
  45. #include "llvm/IR/BasicBlock.h"
  46. #include "llvm/IR/ConstantRange.h"
  47. #include "llvm/IR/DataLayout.h"
  48. #include "llvm/IR/DebugLoc.h"
  49. #include "llvm/IR/Dominators.h"
  50. #include "llvm/IR/Function.h"
  51. #include "llvm/IR/InstrTypes.h"
  52. #include "llvm/IR/Instruction.h"
  53. #include "llvm/IR/Instructions.h"
  54. #include "llvm/IR/Module.h"
  55. #include "llvm/IR/PassManager.h"
  56. #include "llvm/IR/Type.h"
  57. #include "llvm/IR/Value.h"
  58. #include "llvm/InitializePasses.h"
  59. #include "llvm/Support/Compiler.h"
  60. #include "llvm/Support/Debug.h"
  61. #include "llvm/Support/ErrorHandling.h"
  62. #include "llvm/Support/raw_ostream.h"
  63. #include "isl/aff.h"
  64. #include "isl/local_space.h"
  65. #include "isl/map.h"
  66. #include "isl/options.h"
  67. #include "isl/set.h"
  68. #include <cassert>
  69. using namespace llvm;
  70. using namespace polly;
  71. #define DEBUG_TYPE "polly-scops"
  72. STATISTIC(AssumptionsAliasing, "Number of aliasing assumptions taken.");
  73. STATISTIC(AssumptionsInbounds, "Number of inbounds assumptions taken.");
  74. STATISTIC(AssumptionsWrapping, "Number of wrapping assumptions taken.");
  75. STATISTIC(AssumptionsUnsigned, "Number of unsigned assumptions taken.");
  76. STATISTIC(AssumptionsComplexity, "Number of too complex SCoPs.");
  77. STATISTIC(AssumptionsUnprofitable, "Number of unprofitable SCoPs.");
  78. STATISTIC(AssumptionsErrorBlock, "Number of error block assumptions taken.");
  79. STATISTIC(AssumptionsInfiniteLoop, "Number of bounded loop assumptions taken.");
  80. STATISTIC(AssumptionsInvariantLoad,
  81. "Number of invariant loads assumptions taken.");
  82. STATISTIC(AssumptionsDelinearization,
  83. "Number of delinearization assumptions taken.");
  84. STATISTIC(NumScops, "Number of feasible SCoPs after ScopInfo");
  85. STATISTIC(NumLoopsInScop, "Number of loops in scops");
  86. STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after ScopInfo");
  87. STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after ScopInfo");
  88. STATISTIC(NumScopsDepthZero, "Number of scops with maximal loop depth 0");
  89. STATISTIC(NumScopsDepthOne, "Number of scops with maximal loop depth 1");
  90. STATISTIC(NumScopsDepthTwo, "Number of scops with maximal loop depth 2");
  91. STATISTIC(NumScopsDepthThree, "Number of scops with maximal loop depth 3");
  92. STATISTIC(NumScopsDepthFour, "Number of scops with maximal loop depth 4");
  93. STATISTIC(NumScopsDepthFive, "Number of scops with maximal loop depth 5");
  94. STATISTIC(NumScopsDepthLarger,
  95. "Number of scops with maximal loop depth 6 and larger");
  96. STATISTIC(MaxNumLoopsInScop, "Maximal number of loops in scops");
  97. STATISTIC(NumValueWrites, "Number of scalar value writes after ScopInfo");
  98. STATISTIC(
  99. NumValueWritesInLoops,
  100. "Number of scalar value writes nested in affine loops after ScopInfo");
  101. STATISTIC(NumPHIWrites, "Number of scalar phi writes after ScopInfo");
  102. STATISTIC(NumPHIWritesInLoops,
  103. "Number of scalar phi writes nested in affine loops after ScopInfo");
  104. STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo");
  105. STATISTIC(NumSingletonWritesInLoops,
  106. "Number of singleton writes nested in affine loops after ScopInfo");
  107. unsigned const polly::MaxDisjunctsInDomain = 20;
  108. // The number of disjunct in the context after which we stop to add more
  109. // disjuncts. This parameter is there to avoid exponential growth in the
  110. // number of disjunct when adding non-convex sets to the context.
  111. static int const MaxDisjunctsInContext = 4;
  112. // Be a bit more generous for the defined behavior context which is used less
  113. // often.
  114. static int const MaxDisjunktsInDefinedBehaviourContext = 8;
  115. static cl::opt<bool> PollyRemarksMinimal(
  116. "polly-remarks-minimal",
  117. cl::desc("Do not emit remarks about assumptions that are known"),
  118. cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory));
  119. static cl::opt<bool>
  120. IslOnErrorAbort("polly-on-isl-error-abort",
  121. cl::desc("Abort if an isl error is encountered"),
  122. cl::init(true), cl::cat(PollyCategory));
  123. static cl::opt<bool> PollyPreciseInbounds(
  124. "polly-precise-inbounds",
  125. cl::desc("Take more precise inbounds assumptions (do not scale well)"),
  126. cl::Hidden, cl::init(false), cl::cat(PollyCategory));
  127. static cl::opt<bool> PollyIgnoreParamBounds(
  128. "polly-ignore-parameter-bounds",
  129. cl::desc(
  130. "Do not add parameter bounds and do no gist simplify sets accordingly"),
  131. cl::Hidden, cl::init(false), cl::cat(PollyCategory));
  132. static cl::opt<bool> PollyPreciseFoldAccesses(
  133. "polly-precise-fold-accesses",
  134. cl::desc("Fold memory accesses to model more possible delinearizations "
  135. "(does not scale well)"),
  136. cl::Hidden, cl::init(false), cl::cat(PollyCategory));
  137. bool polly::UseInstructionNames;
  138. static cl::opt<bool, true> XUseInstructionNames(
  139. "polly-use-llvm-names",
  140. cl::desc("Use LLVM-IR names when deriving statement names"),
  141. cl::location(UseInstructionNames), cl::Hidden, cl::init(false),
  142. cl::ZeroOrMore, cl::cat(PollyCategory));
  143. static cl::opt<bool> PollyPrintInstructions(
  144. "polly-print-instructions", cl::desc("Output instructions per ScopStmt"),
  145. cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory));
  146. static cl::list<std::string> IslArgs("polly-isl-arg",
  147. cl::value_desc("argument"),
  148. cl::desc("Option passed to ISL"),
  149. cl::ZeroOrMore, cl::cat(PollyCategory));
  150. //===----------------------------------------------------------------------===//
  151. static isl::set addRangeBoundsToSet(isl::set S, const ConstantRange &Range,
  152. int dim, isl::dim type) {
  153. isl::val V;
  154. isl::ctx Ctx = S.ctx();
  155. // The upper and lower bound for a parameter value is derived either from
  156. // the data type of the parameter or from the - possibly more restrictive -
  157. // range metadata.
  158. V = valFromAPInt(Ctx.get(), Range.getSignedMin(), true);
  159. S = S.lower_bound_val(type, dim, V);
  160. V = valFromAPInt(Ctx.get(), Range.getSignedMax(), true);
  161. S = S.upper_bound_val(type, dim, V);
  162. if (Range.isFullSet())
  163. return S;
  164. if (S.n_basic_set().release() > MaxDisjunctsInContext)
  165. return S;
  166. // In case of signed wrapping, we can refine the set of valid values by
  167. // excluding the part not covered by the wrapping range.
  168. if (Range.isSignWrappedSet()) {
  169. V = valFromAPInt(Ctx.get(), Range.getLower(), true);
  170. isl::set SLB = S.lower_bound_val(type, dim, V);
  171. V = valFromAPInt(Ctx.get(), Range.getUpper(), true);
  172. V = V.sub(1);
  173. isl::set SUB = S.upper_bound_val(type, dim, V);
  174. S = SLB.unite(SUB);
  175. }
  176. return S;
  177. }
  178. static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
  179. LoadInst *BasePtrLI = dyn_cast<LoadInst>(BasePtr);
  180. if (!BasePtrLI)
  181. return nullptr;
  182. if (!S->contains(BasePtrLI))
  183. return nullptr;
  184. ScalarEvolution &SE = *S->getSE();
  185. auto *OriginBaseSCEV =
  186. SE.getPointerBase(SE.getSCEV(BasePtrLI->getPointerOperand()));
  187. if (!OriginBaseSCEV)
  188. return nullptr;
  189. auto *OriginBaseSCEVUnknown = dyn_cast<SCEVUnknown>(OriginBaseSCEV);
  190. if (!OriginBaseSCEVUnknown)
  191. return nullptr;
  192. return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(),
  193. MemoryKind::Array);
  194. }
  195. ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl::ctx Ctx,
  196. ArrayRef<const SCEV *> Sizes, MemoryKind Kind,
  197. const DataLayout &DL, Scop *S,
  198. const char *BaseName)
  199. : BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
  200. std::string BasePtrName =
  201. BaseName ? BaseName
  202. : getIslCompatibleName("MemRef", BasePtr, S->getNextArrayIdx(),
  203. Kind == MemoryKind::PHI ? "__phi" : "",
  204. UseInstructionNames);
  205. Id = isl::id::alloc(Ctx, BasePtrName, this);
  206. updateSizes(Sizes);
  207. if (!BasePtr || Kind != MemoryKind::Array) {
  208. BasePtrOriginSAI = nullptr;
  209. return;
  210. }
  211. BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
  212. if (BasePtrOriginSAI)
  213. const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
  214. }
  215. ScopArrayInfo::~ScopArrayInfo() = default;
  216. isl::space ScopArrayInfo::getSpace() const {
  217. auto Space = isl::space(Id.ctx(), 0, getNumberOfDimensions());
  218. Space = Space.set_tuple_id(isl::dim::set, Id);
  219. return Space;
  220. }
  221. bool ScopArrayInfo::isReadOnly() {
  222. isl::union_set WriteSet = S.getWrites().range();
  223. isl::space Space = getSpace();
  224. WriteSet = WriteSet.extract_set(Space);
  225. return bool(WriteSet.is_empty());
  226. }
  227. bool ScopArrayInfo::isCompatibleWith(const ScopArrayInfo *Array) const {
  228. if (Array->getElementType() != getElementType())
  229. return false;
  230. if (Array->getNumberOfDimensions() != getNumberOfDimensions())
  231. return false;
  232. for (unsigned i = 0; i < getNumberOfDimensions(); i++)
  233. if (Array->getDimensionSize(i) != getDimensionSize(i))
  234. return false;
  235. return true;
  236. }
  237. void ScopArrayInfo::updateElementType(Type *NewElementType) {
  238. if (NewElementType == ElementType)
  239. return;
  240. auto OldElementSize = DL.getTypeAllocSizeInBits(ElementType);
  241. auto NewElementSize = DL.getTypeAllocSizeInBits(NewElementType);
  242. if (NewElementSize == OldElementSize || NewElementSize == 0)
  243. return;
  244. if (NewElementSize % OldElementSize == 0 && NewElementSize < OldElementSize) {
  245. ElementType = NewElementType;
  246. } else {
  247. auto GCD = GreatestCommonDivisor64(NewElementSize, OldElementSize);
  248. ElementType = IntegerType::get(ElementType->getContext(), GCD);
  249. }
  250. }
  251. bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
  252. bool CheckConsistency) {
  253. int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
  254. int ExtraDimsNew = NewSizes.size() - SharedDims;
  255. int ExtraDimsOld = DimensionSizes.size() - SharedDims;
  256. if (CheckConsistency) {
  257. for (int i = 0; i < SharedDims; i++) {
  258. auto *NewSize = NewSizes[i + ExtraDimsNew];
  259. auto *KnownSize = DimensionSizes[i + ExtraDimsOld];
  260. if (NewSize && KnownSize && NewSize != KnownSize)
  261. return false;
  262. }
  263. if (DimensionSizes.size() >= NewSizes.size())
  264. return true;
  265. }
  266. DimensionSizes.clear();
  267. DimensionSizes.insert(DimensionSizes.begin(), NewSizes.begin(),
  268. NewSizes.end());
  269. DimensionSizesPw.clear();
  270. for (const SCEV *Expr : DimensionSizes) {
  271. if (!Expr) {
  272. DimensionSizesPw.push_back(isl::pw_aff());
  273. continue;
  274. }
  275. isl::pw_aff Size = S.getPwAffOnly(Expr);
  276. DimensionSizesPw.push_back(Size);
  277. }
  278. return true;
  279. }
  280. std::string ScopArrayInfo::getName() const { return Id.get_name(); }
  281. int ScopArrayInfo::getElemSizeInBytes() const {
  282. return DL.getTypeAllocSize(ElementType);
  283. }
  284. isl::id ScopArrayInfo::getBasePtrId() const { return Id; }
  285. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  286. LLVM_DUMP_METHOD void ScopArrayInfo::dump() const { print(errs()); }
  287. #endif
  288. void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {
  289. OS.indent(8) << *getElementType() << " " << getName();
  290. unsigned u = 0;
  291. if (getNumberOfDimensions() > 0 && !getDimensionSize(0)) {
  292. OS << "[*]";
  293. u++;
  294. }
  295. for (; u < getNumberOfDimensions(); u++) {
  296. OS << "[";
  297. if (SizeAsPwAff) {
  298. isl::pw_aff Size = getDimensionSizePw(u);
  299. OS << " " << Size << " ";
  300. } else {
  301. OS << *getDimensionSize(u);
  302. }
  303. OS << "]";
  304. }
  305. OS << ";";
  306. if (BasePtrOriginSAI)
  307. OS << " [BasePtrOrigin: " << BasePtrOriginSAI->getName() << "]";
  308. OS << " // Element size " << getElemSizeInBytes() << "\n";
  309. }
  310. const ScopArrayInfo *
  311. ScopArrayInfo::getFromAccessFunction(isl::pw_multi_aff PMA) {
  312. isl::id Id = PMA.get_tuple_id(isl::dim::out);
  313. assert(!Id.is_null() && "Output dimension didn't have an ID");
  314. return getFromId(Id);
  315. }
  316. const ScopArrayInfo *ScopArrayInfo::getFromId(isl::id Id) {
  317. void *User = Id.get_user();
  318. const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
  319. return SAI;
  320. }
  321. void MemoryAccess::wrapConstantDimensions() {
  322. auto *SAI = getScopArrayInfo();
  323. isl::space ArraySpace = SAI->getSpace();
  324. isl::ctx Ctx = ArraySpace.ctx();
  325. unsigned DimsArray = SAI->getNumberOfDimensions();
  326. isl::multi_aff DivModAff = isl::multi_aff::identity(
  327. ArraySpace.map_from_domain_and_range(ArraySpace));
  328. isl::local_space LArraySpace = isl::local_space(ArraySpace);
  329. // Begin with last dimension, to iteratively carry into higher dimensions.
  330. for (int i = DimsArray - 1; i > 0; i--) {
  331. auto *DimSize = SAI->getDimensionSize(i);
  332. auto *DimSizeCst = dyn_cast<SCEVConstant>(DimSize);
  333. // This transformation is not applicable to dimensions with dynamic size.
  334. if (!DimSizeCst)
  335. continue;
  336. // This transformation is not applicable to dimensions of size zero.
  337. if (DimSize->isZero())
  338. continue;
  339. isl::val DimSizeVal =
  340. valFromAPInt(Ctx.get(), DimSizeCst->getAPInt(), false);
  341. isl::aff Var = isl::aff::var_on_domain(LArraySpace, isl::dim::set, i);
  342. isl::aff PrevVar =
  343. isl::aff::var_on_domain(LArraySpace, isl::dim::set, i - 1);
  344. // Compute: index % size
  345. // Modulo must apply in the divide of the previous iteration, if any.
  346. isl::aff Modulo = Var.mod(DimSizeVal);
  347. Modulo = Modulo.pullback(DivModAff);
  348. // Compute: floor(index / size)
  349. isl::aff Divide = Var.div(isl::aff(LArraySpace, DimSizeVal));
  350. Divide = Divide.floor();
  351. Divide = Divide.add(PrevVar);
  352. Divide = Divide.pullback(DivModAff);
  353. // Apply Modulo and Divide.
  354. DivModAff = DivModAff.set_aff(i, Modulo);
  355. DivModAff = DivModAff.set_aff(i - 1, Divide);
  356. }
  357. // Apply all modulo/divides on the accesses.
  358. isl::map Relation = AccessRelation;
  359. Relation = Relation.apply_range(isl::map::from_multi_aff(DivModAff));
  360. Relation = Relation.detect_equalities();
  361. AccessRelation = Relation;
  362. }
  363. void MemoryAccess::updateDimensionality() {
  364. auto *SAI = getScopArrayInfo();
  365. isl::space ArraySpace = SAI->getSpace();
  366. isl::space AccessSpace = AccessRelation.get_space().range();
  367. isl::ctx Ctx = ArraySpace.ctx();
  368. unsigned DimsArray = unsignedFromIslSize(ArraySpace.dim(isl::dim::set));
  369. unsigned DimsAccess = unsignedFromIslSize(AccessSpace.dim(isl::dim::set));
  370. assert(DimsArray >= DimsAccess);
  371. unsigned DimsMissing = DimsArray - DimsAccess;
  372. auto *BB = getStatement()->getEntryBlock();
  373. auto &DL = BB->getModule()->getDataLayout();
  374. unsigned ArrayElemSize = SAI->getElemSizeInBytes();
  375. unsigned ElemBytes = DL.getTypeAllocSize(getElementType());
  376. isl::map Map = isl::map::from_domain_and_range(
  377. isl::set::universe(AccessSpace), isl::set::universe(ArraySpace));
  378. for (auto i : seq<unsigned>(0, DimsMissing))
  379. Map = Map.fix_si(isl::dim::out, i, 0);
  380. for (auto i : seq<unsigned>(DimsMissing, DimsArray))
  381. Map = Map.equate(isl::dim::in, i - DimsMissing, isl::dim::out, i);
  382. AccessRelation = AccessRelation.apply_range(Map);
  383. // For the non delinearized arrays, divide the access function of the last
  384. // subscript by the size of the elements in the array.
  385. //
  386. // A stride one array access in C expressed as A[i] is expressed in
  387. // LLVM-IR as something like A[i * elementsize]. This hides the fact that
  388. // two subsequent values of 'i' index two values that are stored next to
  389. // each other in memory. By this division we make this characteristic
  390. // obvious again. If the base pointer was accessed with offsets not divisible
  391. // by the accesses element size, we will have chosen a smaller ArrayElemSize
  392. // that divides the offsets of all accesses to this base pointer.
  393. if (DimsAccess == 1) {
  394. isl::val V = isl::val(Ctx, ArrayElemSize);
  395. AccessRelation = AccessRelation.floordiv_val(V);
  396. }
  397. // We currently do this only if we added at least one dimension, which means
  398. // some dimension's indices have not been specified, an indicator that some
  399. // index values have been added together.
  400. // TODO: Investigate general usefulness; Effect on unit tests is to make index
  401. // expressions more complicated.
  402. if (DimsMissing)
  403. wrapConstantDimensions();
  404. if (!isAffine())
  405. computeBoundsOnAccessRelation(ArrayElemSize);
  406. // Introduce multi-element accesses in case the type loaded by this memory
  407. // access is larger than the canonical element type of the array.
  408. //
  409. // An access ((float *)A)[i] to an array char *A is modeled as
  410. // {[i] -> A[o] : 4 i <= o <= 4 i + 3
  411. if (ElemBytes > ArrayElemSize) {
  412. assert(ElemBytes % ArrayElemSize == 0 &&
  413. "Loaded element size should be multiple of canonical element size");
  414. assert(DimsArray >= 1);
  415. isl::map Map = isl::map::from_domain_and_range(
  416. isl::set::universe(ArraySpace), isl::set::universe(ArraySpace));
  417. for (auto i : seq<unsigned>(0, DimsArray - 1))
  418. Map = Map.equate(isl::dim::in, i, isl::dim::out, i);
  419. isl::constraint C;
  420. isl::local_space LS;
  421. LS = isl::local_space(Map.get_space());
  422. int Num = ElemBytes / getScopArrayInfo()->getElemSizeInBytes();
  423. C = isl::constraint::alloc_inequality(LS);
  424. C = C.set_constant_val(isl::val(Ctx, Num - 1));
  425. C = C.set_coefficient_si(isl::dim::in, DimsArray - 1, 1);
  426. C = C.set_coefficient_si(isl::dim::out, DimsArray - 1, -1);
  427. Map = Map.add_constraint(C);
  428. C = isl::constraint::alloc_inequality(LS);
  429. C = C.set_coefficient_si(isl::dim::in, DimsArray - 1, -1);
  430. C = C.set_coefficient_si(isl::dim::out, DimsArray - 1, 1);
  431. C = C.set_constant_val(isl::val(Ctx, 0));
  432. Map = Map.add_constraint(C);
  433. AccessRelation = AccessRelation.apply_range(Map);
  434. }
  435. }
  436. const std::string
  437. MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
  438. switch (RT) {
  439. case MemoryAccess::RT_NONE:
  440. llvm_unreachable("Requested a reduction operator string for a memory "
  441. "access which isn't a reduction");
  442. case MemoryAccess::RT_ADD:
  443. return "+";
  444. case MemoryAccess::RT_MUL:
  445. return "*";
  446. case MemoryAccess::RT_BOR:
  447. return "|";
  448. case MemoryAccess::RT_BXOR:
  449. return "^";
  450. case MemoryAccess::RT_BAND:
  451. return "&";
  452. }
  453. llvm_unreachable("Unknown reduction type");
  454. }
  455. const ScopArrayInfo *MemoryAccess::getOriginalScopArrayInfo() const {
  456. isl::id ArrayId = getArrayId();
  457. void *User = ArrayId.get_user();
  458. const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
  459. return SAI;
  460. }
  461. const ScopArrayInfo *MemoryAccess::getLatestScopArrayInfo() const {
  462. isl::id ArrayId = getLatestArrayId();
  463. void *User = ArrayId.get_user();
  464. const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
  465. return SAI;
  466. }
  467. isl::id MemoryAccess::getOriginalArrayId() const {
  468. return AccessRelation.get_tuple_id(isl::dim::out);
  469. }
  470. isl::id MemoryAccess::getLatestArrayId() const {
  471. if (!hasNewAccessRelation())
  472. return getOriginalArrayId();
  473. return NewAccessRelation.get_tuple_id(isl::dim::out);
  474. }
  475. isl::map MemoryAccess::getAddressFunction() const {
  476. return getAccessRelation().lexmin();
  477. }
  478. isl::pw_multi_aff
  479. MemoryAccess::applyScheduleToAccessRelation(isl::union_map USchedule) const {
  480. isl::map Schedule, ScheduledAccRel;
  481. isl::union_set UDomain;
  482. UDomain = getStatement()->getDomain();
  483. USchedule = USchedule.intersect_domain(UDomain);
  484. Schedule = isl::map::from_union_map(USchedule);
  485. ScheduledAccRel = getAddressFunction().apply_domain(Schedule);
  486. return isl::pw_multi_aff::from_map(ScheduledAccRel);
  487. }
  488. isl::map MemoryAccess::getOriginalAccessRelation() const {
  489. return AccessRelation;
  490. }
  491. std::string MemoryAccess::getOriginalAccessRelationStr() const {
  492. return stringFromIslObj(AccessRelation);
  493. }
  494. isl::space MemoryAccess::getOriginalAccessRelationSpace() const {
  495. return AccessRelation.get_space();
  496. }
  497. isl::map MemoryAccess::getNewAccessRelation() const {
  498. return NewAccessRelation;
  499. }
  500. std::string MemoryAccess::getNewAccessRelationStr() const {
  501. return stringFromIslObj(NewAccessRelation);
  502. }
  503. std::string MemoryAccess::getAccessRelationStr() const {
  504. return stringFromIslObj(getAccessRelation());
  505. }
  506. isl::basic_map MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
  507. isl::space Space = isl::space(Statement->getIslCtx(), 0, 1);
  508. Space = Space.align_params(Statement->getDomainSpace());
  509. return isl::basic_map::from_domain_and_range(
  510. isl::basic_set::universe(Statement->getDomainSpace()),
  511. isl::basic_set::universe(Space));
  512. }
  513. // Formalize no out-of-bound access assumption
  514. //
  515. // When delinearizing array accesses we optimistically assume that the
  516. // delinearized accesses do not access out of bound locations (the subscript
  517. // expression of each array evaluates for each statement instance that is
  518. // executed to a value that is larger than zero and strictly smaller than the
  519. // size of the corresponding dimension). The only exception is the outermost
  520. // dimension for which we do not need to assume any upper bound. At this point
  521. // we formalize this assumption to ensure that at code generation time the
  522. // relevant run-time checks can be generated.
  523. //
  524. // To find the set of constraints necessary to avoid out of bound accesses, we
  525. // first build the set of data locations that are not within array bounds. We
  526. // then apply the reverse access relation to obtain the set of iterations that
  527. // may contain invalid accesses and reduce this set of iterations to the ones
  528. // that are actually executed by intersecting them with the domain of the
  529. // statement. If we now project out all loop dimensions, we obtain a set of
  530. // parameters that may cause statement instances to be executed that may
  531. // possibly yield out of bound memory accesses. The complement of these
  532. // constraints is the set of constraints that needs to be assumed to ensure such
  533. // statement instances are never executed.
  534. isl::set MemoryAccess::assumeNoOutOfBound() {
  535. auto *SAI = getScopArrayInfo();
  536. isl::space Space = getOriginalAccessRelationSpace().range();
  537. isl::set Outside = isl::set::empty(Space);
  538. for (int i = 1, Size = Space.dim(isl::dim::set).release(); i < Size; ++i) {
  539. isl::local_space LS(Space);
  540. isl::pw_aff Var = isl::pw_aff::var_on_domain(LS, isl::dim::set, i);
  541. isl::pw_aff Zero = isl::pw_aff(LS);
  542. isl::set DimOutside = Var.lt_set(Zero);
  543. isl::pw_aff SizeE = SAI->getDimensionSizePw(i);
  544. SizeE = SizeE.add_dims(isl::dim::in, Space.dim(isl::dim::set).release());
  545. SizeE = SizeE.set_tuple_id(isl::dim::in, Space.get_tuple_id(isl::dim::set));
  546. DimOutside = DimOutside.unite(SizeE.le_set(Var));
  547. Outside = Outside.unite(DimOutside);
  548. }
  549. Outside = Outside.apply(getAccessRelation().reverse());
  550. Outside = Outside.intersect(Statement->getDomain());
  551. Outside = Outside.params();
  552. // Remove divs to avoid the construction of overly complicated assumptions.
  553. // Doing so increases the set of parameter combinations that are assumed to
  554. // not appear. This is always save, but may make the resulting run-time check
  555. // bail out more often than strictly necessary.
  556. Outside = Outside.remove_divs();
  557. Outside = Outside.complement();
  558. if (!PollyPreciseInbounds)
  559. Outside = Outside.gist_params(Statement->getDomain().params());
  560. return Outside;
  561. }
  562. void MemoryAccess::buildMemIntrinsicAccessRelation() {
  563. assert(isMemoryIntrinsic());
  564. assert(Subscripts.size() == 2 && Sizes.size() == 1);
  565. isl::pw_aff SubscriptPWA = getPwAff(Subscripts[0]);
  566. isl::map SubscriptMap = isl::map::from_pw_aff(SubscriptPWA);
  567. isl::map LengthMap;
  568. if (Subscripts[1] == nullptr) {
  569. LengthMap = isl::map::universe(SubscriptMap.get_space());
  570. } else {
  571. isl::pw_aff LengthPWA = getPwAff(Subscripts[1]);
  572. LengthMap = isl::map::from_pw_aff(LengthPWA);
  573. isl::space RangeSpace = LengthMap.get_space().range();
  574. LengthMap = LengthMap.apply_range(isl::map::lex_gt(RangeSpace));
  575. }
  576. LengthMap = LengthMap.lower_bound_si(isl::dim::out, 0, 0);
  577. LengthMap = LengthMap.align_params(SubscriptMap.get_space());
  578. SubscriptMap = SubscriptMap.align_params(LengthMap.get_space());
  579. LengthMap = LengthMap.sum(SubscriptMap);
  580. AccessRelation =
  581. LengthMap.set_tuple_id(isl::dim::in, getStatement()->getDomainId());
  582. }
  583. void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
  584. ScalarEvolution *SE = Statement->getParent()->getSE();
  585. auto MAI = MemAccInst(getAccessInstruction());
  586. if (isa<MemIntrinsic>(MAI))
  587. return;
  588. Value *Ptr = MAI.getPointerOperand();
  589. if (!Ptr || !SE->isSCEVable(Ptr->getType()))
  590. return;
  591. auto *PtrSCEV = SE->getSCEV(Ptr);
  592. if (isa<SCEVCouldNotCompute>(PtrSCEV))
  593. return;
  594. auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
  595. if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
  596. PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
  597. const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
  598. if (Range.isFullSet())
  599. return;
  600. if (Range.isUpperWrapped() || Range.isSignWrappedSet())
  601. return;
  602. bool isWrapping = Range.isSignWrappedSet();
  603. unsigned BW = Range.getBitWidth();
  604. const auto One = APInt(BW, 1);
  605. const auto LB = isWrapping ? Range.getLower() : Range.getSignedMin();
  606. const auto UB = isWrapping ? (Range.getUpper() - One) : Range.getSignedMax();
  607. auto Min = LB.sdiv(APInt(BW, ElementSize));
  608. auto Max = UB.sdiv(APInt(BW, ElementSize)) + One;
  609. assert(Min.sle(Max) && "Minimum expected to be less or equal than max");
  610. isl::map Relation = AccessRelation;
  611. isl::set AccessRange = Relation.range();
  612. AccessRange = addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0,
  613. isl::dim::set);
  614. AccessRelation = Relation.intersect_range(AccessRange);
  615. }
  616. void MemoryAccess::foldAccessRelation() {
  617. if (Sizes.size() < 2 || isa<SCEVConstant>(Sizes[1]))
  618. return;
  619. int Size = Subscripts.size();
  620. isl::map NewAccessRelation = AccessRelation;
  621. for (int i = Size - 2; i >= 0; --i) {
  622. isl::space Space;
  623. isl::map MapOne, MapTwo;
  624. isl::pw_aff DimSize = getPwAff(Sizes[i + 1]);
  625. isl::space SpaceSize = DimSize.get_space();
  626. isl::id ParamId = SpaceSize.get_dim_id(isl::dim::param, 0);
  627. Space = AccessRelation.get_space();
  628. Space = Space.range().map_from_set();
  629. Space = Space.align_params(SpaceSize);
  630. int ParamLocation = Space.find_dim_by_id(isl::dim::param, ParamId);
  631. MapOne = isl::map::universe(Space);
  632. for (int j = 0; j < Size; ++j)
  633. MapOne = MapOne.equate(isl::dim::in, j, isl::dim::out, j);
  634. MapOne = MapOne.lower_bound_si(isl::dim::in, i + 1, 0);
  635. MapTwo = isl::map::universe(Space);
  636. for (int j = 0; j < Size; ++j)
  637. if (j < i || j > i + 1)
  638. MapTwo = MapTwo.equate(isl::dim::in, j, isl::dim::out, j);
  639. isl::local_space LS(Space);
  640. isl::constraint C;
  641. C = isl::constraint::alloc_equality(LS);
  642. C = C.set_constant_si(-1);
  643. C = C.set_coefficient_si(isl::dim::in, i, 1);
  644. C = C.set_coefficient_si(isl::dim::out, i, -1);
  645. MapTwo = MapTwo.add_constraint(C);
  646. C = isl::constraint::alloc_equality(LS);
  647. C = C.set_coefficient_si(isl::dim::in, i + 1, 1);
  648. C = C.set_coefficient_si(isl::dim::out, i + 1, -1);
  649. C = C.set_coefficient_si(isl::dim::param, ParamLocation, 1);
  650. MapTwo = MapTwo.add_constraint(C);
  651. MapTwo = MapTwo.upper_bound_si(isl::dim::in, i + 1, -1);
  652. MapOne = MapOne.unite(MapTwo);
  653. NewAccessRelation = NewAccessRelation.apply_range(MapOne);
  654. }
  655. isl::id BaseAddrId = getScopArrayInfo()->getBasePtrId();
  656. isl::space Space = Statement->getDomainSpace();
  657. NewAccessRelation = NewAccessRelation.set_tuple_id(
  658. isl::dim::in, Space.get_tuple_id(isl::dim::set));
  659. NewAccessRelation = NewAccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
  660. NewAccessRelation = NewAccessRelation.gist_domain(Statement->getDomain());
  661. // Access dimension folding might in certain cases increase the number of
  662. // disjuncts in the memory access, which can possibly complicate the generated
  663. // run-time checks and can lead to costly compilation.
  664. if (!PollyPreciseFoldAccesses && NewAccessRelation.n_basic_map().release() >
  665. AccessRelation.n_basic_map().release()) {
  666. } else {
  667. AccessRelation = NewAccessRelation;
  668. }
  669. }
  670. void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
  671. assert(AccessRelation.is_null() && "AccessRelation already built");
  672. // Initialize the invalid domain which describes all iterations for which the
  673. // access relation is not modeled correctly.
  674. isl::set StmtInvalidDomain = getStatement()->getInvalidDomain();
  675. InvalidDomain = isl::set::empty(StmtInvalidDomain.get_space());
  676. isl::ctx Ctx = Id.ctx();
  677. isl::id BaseAddrId = SAI->getBasePtrId();
  678. if (getAccessInstruction() && isa<MemIntrinsic>(getAccessInstruction())) {
  679. buildMemIntrinsicAccessRelation();
  680. AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
  681. return;
  682. }
  683. if (!isAffine()) {
  684. // We overapproximate non-affine accesses with a possible access to the
  685. // whole array. For read accesses it does not make a difference, if an
  686. // access must or may happen. However, for write accesses it is important to
  687. // differentiate between writes that must happen and writes that may happen.
  688. if (AccessRelation.is_null())
  689. AccessRelation = createBasicAccessMap(Statement);
  690. AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
  691. return;
  692. }
  693. isl::space Space = isl::space(Ctx, 0, Statement->getNumIterators(), 0);
  694. AccessRelation = isl::map::universe(Space);
  695. for (int i = 0, Size = Subscripts.size(); i < Size; ++i) {
  696. isl::pw_aff Affine = getPwAff(Subscripts[i]);
  697. isl::map SubscriptMap = isl::map::from_pw_aff(Affine);
  698. AccessRelation = AccessRelation.flat_range_product(SubscriptMap);
  699. }
  700. Space = Statement->getDomainSpace();
  701. AccessRelation = AccessRelation.set_tuple_id(
  702. isl::dim::in, Space.get_tuple_id(isl::dim::set));
  703. AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
  704. AccessRelation = AccessRelation.gist_domain(Statement->getDomain());
  705. }
  706. MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
  707. AccessType AccType, Value *BaseAddress,
  708. Type *ElementType, bool Affine,
  709. ArrayRef<const SCEV *> Subscripts,
  710. ArrayRef<const SCEV *> Sizes, Value *AccessValue,
  711. MemoryKind Kind)
  712. : Kind(Kind), AccType(AccType), Statement(Stmt), InvalidDomain(),
  713. BaseAddr(BaseAddress), ElementType(ElementType),
  714. Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
  715. AccessValue(AccessValue), IsAffine(Affine),
  716. Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(),
  717. NewAccessRelation() {
  718. static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
  719. const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
  720. std::string IdName = Stmt->getBaseName() + Access;
  721. Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
  722. }
  723. MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel)
  724. : Kind(MemoryKind::Array), AccType(AccType), Statement(Stmt),
  725. InvalidDomain(), AccessRelation(), NewAccessRelation(AccRel) {
  726. isl::id ArrayInfoId = NewAccessRelation.get_tuple_id(isl::dim::out);
  727. auto *SAI = ScopArrayInfo::getFromId(ArrayInfoId);
  728. Sizes.push_back(nullptr);
  729. for (unsigned i = 1; i < SAI->getNumberOfDimensions(); i++)
  730. Sizes.push_back(SAI->getDimensionSize(i));
  731. ElementType = SAI->getElementType();
  732. BaseAddr = SAI->getBasePtr();
  733. static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
  734. const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
  735. std::string IdName = Stmt->getBaseName() + Access;
  736. Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
  737. }
  738. MemoryAccess::~MemoryAccess() = default;
  739. void MemoryAccess::realignParams() {
  740. isl::set Ctx = Statement->getParent()->getContext();
  741. InvalidDomain = InvalidDomain.gist_params(Ctx);
  742. AccessRelation = AccessRelation.gist_params(Ctx);
  743. // Predictable parameter order is required for JSON imports. Ensure alignment
  744. // by explicitly calling align_params.
  745. isl::space CtxSpace = Ctx.get_space();
  746. InvalidDomain = InvalidDomain.align_params(CtxSpace);
  747. AccessRelation = AccessRelation.align_params(CtxSpace);
  748. }
  749. const std::string MemoryAccess::getReductionOperatorStr() const {
  750. return MemoryAccess::getReductionOperatorStr(getReductionType());
  751. }
  752. isl::id MemoryAccess::getId() const { return Id; }
  753. raw_ostream &polly::operator<<(raw_ostream &OS,
  754. MemoryAccess::ReductionType RT) {
  755. if (RT == MemoryAccess::RT_NONE)
  756. OS << "NONE";
  757. else
  758. OS << MemoryAccess::getReductionOperatorStr(RT);
  759. return OS;
  760. }
  761. void MemoryAccess::print(raw_ostream &OS) const {
  762. switch (AccType) {
  763. case READ:
  764. OS.indent(12) << "ReadAccess :=\t";
  765. break;
  766. case MUST_WRITE:
  767. OS.indent(12) << "MustWriteAccess :=\t";
  768. break;
  769. case MAY_WRITE:
  770. OS.indent(12) << "MayWriteAccess :=\t";
  771. break;
  772. }
  773. OS << "[Reduction Type: " << getReductionType() << "] ";
  774. OS << "[Scalar: " << isScalarKind() << "]\n";
  775. OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
  776. if (hasNewAccessRelation())
  777. OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n";
  778. }
  779. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  780. LLVM_DUMP_METHOD void MemoryAccess::dump() const { print(errs()); }
  781. #endif
  782. isl::pw_aff MemoryAccess::getPwAff(const SCEV *E) {
  783. auto *Stmt = getStatement();
  784. PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock());
  785. isl::set StmtDom = getStatement()->getDomain();
  786. StmtDom = StmtDom.reset_tuple_id();
  787. isl::set NewInvalidDom = StmtDom.intersect(PWAC.second);
  788. InvalidDomain = InvalidDomain.unite(NewInvalidDom);
  789. return PWAC.first;
  790. }
  791. // Create a map in the size of the provided set domain, that maps from the
  792. // one element of the provided set domain to another element of the provided
  793. // set domain.
  794. // The mapping is limited to all points that are equal in all but the last
  795. // dimension and for which the last dimension of the input is strict smaller
  796. // than the last dimension of the output.
  797. //
  798. // getEqualAndLarger(set[i0, i1, ..., iX]):
  799. //
  800. // set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
  801. // : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
  802. //
  803. static isl::map getEqualAndLarger(isl::space SetDomain) {
  804. isl::space Space = SetDomain.map_from_set();
  805. isl::map Map = isl::map::universe(Space);
  806. unsigned lastDimension = Map.domain_tuple_dim().release() - 1;
  807. // Set all but the last dimension to be equal for the input and output
  808. //
  809. // input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
  810. // : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
  811. for (unsigned i = 0; i < lastDimension; ++i)
  812. Map = Map.equate(isl::dim::in, i, isl::dim::out, i);
  813. // Set the last dimension of the input to be strict smaller than the
  814. // last dimension of the output.
  815. //
  816. // input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
  817. Map = Map.order_lt(isl::dim::in, lastDimension, isl::dim::out, lastDimension);
  818. return Map;
  819. }
  820. isl::set MemoryAccess::getStride(isl::map Schedule) const {
  821. isl::map AccessRelation = getAccessRelation();
  822. isl::space Space = Schedule.get_space().range();
  823. isl::map NextScatt = getEqualAndLarger(Space);
  824. Schedule = Schedule.reverse();
  825. NextScatt = NextScatt.lexmin();
  826. NextScatt = NextScatt.apply_range(Schedule);
  827. NextScatt = NextScatt.apply_range(AccessRelation);
  828. NextScatt = NextScatt.apply_domain(Schedule);
  829. NextScatt = NextScatt.apply_domain(AccessRelation);
  830. isl::set Deltas = NextScatt.deltas();
  831. return Deltas;
  832. }
  833. bool MemoryAccess::isStrideX(isl::map Schedule, int StrideWidth) const {
  834. isl::set Stride, StrideX;
  835. bool IsStrideX;
  836. Stride = getStride(Schedule);
  837. StrideX = isl::set::universe(Stride.get_space());
  838. int Size = unsignedFromIslSize(StrideX.tuple_dim());
  839. for (auto i : seq<int>(0, Size - 1))
  840. StrideX = StrideX.fix_si(isl::dim::set, i, 0);
  841. StrideX = StrideX.fix_si(isl::dim::set, Size - 1, StrideWidth);
  842. IsStrideX = Stride.is_subset(StrideX);
  843. return IsStrideX;
  844. }
  845. bool MemoryAccess::isStrideZero(isl::map Schedule) const {
  846. return isStrideX(Schedule, 0);
  847. }
  848. bool MemoryAccess::isStrideOne(isl::map Schedule) const {
  849. return isStrideX(Schedule, 1);
  850. }
  851. void MemoryAccess::setAccessRelation(isl::map NewAccess) {
  852. AccessRelation = NewAccess;
  853. }
  854. void MemoryAccess::setNewAccessRelation(isl::map NewAccess) {
  855. assert(!NewAccess.is_null());
  856. #ifndef NDEBUG
  857. // Check domain space compatibility.
  858. isl::space NewSpace = NewAccess.get_space();
  859. isl::space NewDomainSpace = NewSpace.domain();
  860. isl::space OriginalDomainSpace = getStatement()->getDomainSpace();
  861. assert(OriginalDomainSpace.has_equal_tuples(NewDomainSpace));
  862. // Reads must be executed unconditionally. Writes might be executed in a
  863. // subdomain only.
  864. if (isRead()) {
  865. // Check whether there is an access for every statement instance.
  866. isl::set StmtDomain = getStatement()->getDomain();
  867. isl::set DefinedContext =
  868. getStatement()->getParent()->getBestKnownDefinedBehaviorContext();
  869. StmtDomain = StmtDomain.intersect_params(DefinedContext);
  870. isl::set NewDomain = NewAccess.domain();
  871. assert(!StmtDomain.is_subset(NewDomain).is_false() &&
  872. "Partial READ accesses not supported");
  873. }
  874. isl::space NewAccessSpace = NewAccess.get_space();
  875. assert(NewAccessSpace.has_tuple_id(isl::dim::set) &&
  876. "Must specify the array that is accessed");
  877. isl::id NewArrayId = NewAccessSpace.get_tuple_id(isl::dim::set);
  878. auto *SAI = static_cast<ScopArrayInfo *>(NewArrayId.get_user());
  879. assert(SAI && "Must set a ScopArrayInfo");
  880. if (SAI->isArrayKind() && SAI->getBasePtrOriginSAI()) {
  881. InvariantEquivClassTy *EqClass =
  882. getStatement()->getParent()->lookupInvariantEquivClass(
  883. SAI->getBasePtr());
  884. assert(EqClass &&
  885. "Access functions to indirect arrays must have an invariant and "
  886. "hoisted base pointer");
  887. }
  888. // Check whether access dimensions correspond to number of dimensions of the
  889. // accesses array.
  890. unsigned Dims = SAI->getNumberOfDimensions();
  891. unsigned SpaceSize = unsignedFromIslSize(NewAccessSpace.dim(isl::dim::set));
  892. assert(SpaceSize == Dims && "Access dims must match array dims");
  893. #endif
  894. NewAccess = NewAccess.gist_params(getStatement()->getParent()->getContext());
  895. NewAccess = NewAccess.gist_domain(getStatement()->getDomain());
  896. NewAccessRelation = NewAccess;
  897. }
  898. bool MemoryAccess::isLatestPartialAccess() const {
  899. isl::set StmtDom = getStatement()->getDomain();
  900. isl::set AccDom = getLatestAccessRelation().domain();
  901. return !StmtDom.is_subset(AccDom);
  902. }
  903. //===----------------------------------------------------------------------===//
  904. isl::map ScopStmt::getSchedule() const {
  905. isl::set Domain = getDomain();
  906. if (Domain.is_empty())
  907. return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace())));
  908. auto Schedule = getParent()->getSchedule();
  909. if (Schedule.is_null())
  910. return {};
  911. Schedule = Schedule.intersect_domain(isl::union_set(Domain));
  912. if (Schedule.is_empty())
  913. return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace())));
  914. isl::map M = M.from_union_map(Schedule);
  915. M = M.coalesce();
  916. M = M.gist_domain(Domain);
  917. M = M.coalesce();
  918. return M;
  919. }
  920. void ScopStmt::restrictDomain(isl::set NewDomain) {
  921. assert(NewDomain.is_subset(Domain) &&
  922. "New domain is not a subset of old domain!");
  923. Domain = NewDomain;
  924. }
  925. void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) {
  926. Instruction *AccessInst = Access->getAccessInstruction();
  927. if (Access->isArrayKind()) {
  928. MemoryAccessList &MAL = InstructionToAccess[AccessInst];
  929. MAL.emplace_front(Access);
  930. } else if (Access->isValueKind() && Access->isWrite()) {
  931. Instruction *AccessVal = cast<Instruction>(Access->getAccessValue());
  932. assert(!ValueWrites.lookup(AccessVal));
  933. ValueWrites[AccessVal] = Access;
  934. } else if (Access->isValueKind() && Access->isRead()) {
  935. Value *AccessVal = Access->getAccessValue();
  936. assert(!ValueReads.lookup(AccessVal));
  937. ValueReads[AccessVal] = Access;
  938. } else if (Access->isAnyPHIKind() && Access->isWrite()) {
  939. PHINode *PHI = cast<PHINode>(Access->getAccessValue());
  940. assert(!PHIWrites.lookup(PHI));
  941. PHIWrites[PHI] = Access;
  942. } else if (Access->isAnyPHIKind() && Access->isRead()) {
  943. PHINode *PHI = cast<PHINode>(Access->getAccessValue());
  944. assert(!PHIReads.lookup(PHI));
  945. PHIReads[PHI] = Access;
  946. }
  947. if (Prepend) {
  948. MemAccs.insert(MemAccs.begin(), Access);
  949. return;
  950. }
  951. MemAccs.push_back(Access);
  952. }
  953. void ScopStmt::realignParams() {
  954. for (MemoryAccess *MA : *this)
  955. MA->realignParams();
  956. simplify(InvalidDomain);
  957. simplify(Domain);
  958. isl::set Ctx = Parent.getContext();
  959. InvalidDomain = InvalidDomain.gist_params(Ctx);
  960. Domain = Domain.gist_params(Ctx);
  961. // Predictable parameter order is required for JSON imports. Ensure alignment
  962. // by explicitly calling align_params.
  963. isl::space CtxSpace = Ctx.get_space();
  964. InvalidDomain = InvalidDomain.align_params(CtxSpace);
  965. Domain = Domain.align_params(CtxSpace);
  966. }
  967. ScopStmt::ScopStmt(Scop &parent, Region &R, StringRef Name,
  968. Loop *SurroundingLoop,
  969. std::vector<Instruction *> EntryBlockInstructions)
  970. : Parent(parent), InvalidDomain(), Domain(), R(&R), Build(), BaseName(Name),
  971. SurroundingLoop(SurroundingLoop), Instructions(EntryBlockInstructions) {}
  972. ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, StringRef Name,
  973. Loop *SurroundingLoop,
  974. std::vector<Instruction *> Instructions)
  975. : Parent(parent), InvalidDomain(), Domain(), BB(&bb), Build(),
  976. BaseName(Name), SurroundingLoop(SurroundingLoop),
  977. Instructions(Instructions) {}
  978. ScopStmt::ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
  979. isl::set NewDomain)
  980. : Parent(parent), InvalidDomain(), Domain(NewDomain), Build() {
  981. BaseName = getIslCompatibleName("CopyStmt_", "",
  982. std::to_string(parent.getCopyStmtsNum()));
  983. isl::id Id = isl::id::alloc(getIslCtx(), getBaseName(), this);
  984. Domain = Domain.set_tuple_id(Id);
  985. TargetRel = TargetRel.set_tuple_id(isl::dim::in, Id);
  986. auto *Access =
  987. new MemoryAccess(this, MemoryAccess::AccessType::MUST_WRITE, TargetRel);
  988. parent.addAccessFunction(Access);
  989. addAccess(Access);
  990. SourceRel = SourceRel.set_tuple_id(isl::dim::in, Id);
  991. Access = new MemoryAccess(this, MemoryAccess::AccessType::READ, SourceRel);
  992. parent.addAccessFunction(Access);
  993. addAccess(Access);
  994. }
  995. ScopStmt::~ScopStmt() = default;
  996. std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
  997. std::string ScopStmt::getScheduleStr() const {
  998. return stringFromIslObj(getSchedule());
  999. }
  1000. void ScopStmt::setInvalidDomain(isl::set ID) { InvalidDomain = ID; }
  1001. BasicBlock *ScopStmt::getEntryBlock() const {
  1002. if (isBlockStmt())
  1003. return getBasicBlock();
  1004. return getRegion()->getEntry();
  1005. }
  1006. unsigned ScopStmt::getNumIterators() const { return NestLoops.size(); }
  1007. const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
  1008. Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
  1009. return NestLoops[Dimension];
  1010. }
  1011. isl::ctx ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
  1012. isl::set ScopStmt::getDomain() const { return Domain; }
  1013. isl::space ScopStmt::getDomainSpace() const { return Domain.get_space(); }
  1014. isl::id ScopStmt::getDomainId() const { return Domain.get_tuple_id(); }
  1015. void ScopStmt::printInstructions(raw_ostream &OS) const {
  1016. OS << "Instructions {\n";
  1017. for (Instruction *Inst : Instructions)
  1018. OS.indent(16) << *Inst << "\n";
  1019. OS.indent(12) << "}\n";
  1020. }
  1021. void ScopStmt::print(raw_ostream &OS, bool PrintInstructions) const {
  1022. OS << "\t" << getBaseName() << "\n";
  1023. OS.indent(12) << "Domain :=\n";
  1024. if (!Domain.is_null()) {
  1025. OS.indent(16) << getDomainStr() << ";\n";
  1026. } else
  1027. OS.indent(16) << "n/a\n";
  1028. OS.indent(12) << "Schedule :=\n";
  1029. if (!Domain.is_null()) {
  1030. OS.indent(16) << getScheduleStr() << ";\n";
  1031. } else
  1032. OS.indent(16) << "n/a\n";
  1033. for (MemoryAccess *Access : MemAccs)
  1034. Access->print(OS);
  1035. if (PrintInstructions)
  1036. printInstructions(OS.indent(12));
  1037. }
  1038. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  1039. LLVM_DUMP_METHOD void ScopStmt::dump() const { print(dbgs(), true); }
  1040. #endif
  1041. void ScopStmt::removeAccessData(MemoryAccess *MA) {
  1042. if (MA->isRead() && MA->isOriginalValueKind()) {
  1043. bool Found = ValueReads.erase(MA->getAccessValue());
  1044. (void)Found;
  1045. assert(Found && "Expected access data not found");
  1046. }
  1047. if (MA->isWrite() && MA->isOriginalValueKind()) {
  1048. bool Found = ValueWrites.erase(cast<Instruction>(MA->getAccessValue()));
  1049. (void)Found;
  1050. assert(Found && "Expected access data not found");
  1051. }
  1052. if (MA->isWrite() && MA->isOriginalAnyPHIKind()) {
  1053. bool Found = PHIWrites.erase(cast<PHINode>(MA->getAccessInstruction()));
  1054. (void)Found;
  1055. assert(Found && "Expected access data not found");
  1056. }
  1057. if (MA->isRead() && MA->isOriginalAnyPHIKind()) {
  1058. bool Found = PHIReads.erase(cast<PHINode>(MA->getAccessInstruction()));
  1059. (void)Found;
  1060. assert(Found && "Expected access data not found");
  1061. }
  1062. }
  1063. void ScopStmt::removeMemoryAccess(MemoryAccess *MA) {
  1064. // Remove the memory accesses from this statement together with all scalar
  1065. // accesses that were caused by it. MemoryKind::Value READs have no access
  1066. // instruction, hence would not be removed by this function. However, it is
  1067. // only used for invariant LoadInst accesses, its arguments are always affine,
  1068. // hence synthesizable, and therefore there are no MemoryKind::Value READ
  1069. // accesses to be removed.
  1070. auto Predicate = [&](MemoryAccess *Acc) {
  1071. return Acc->getAccessInstruction() == MA->getAccessInstruction();
  1072. };
  1073. for (auto *MA : MemAccs) {
  1074. if (Predicate(MA)) {
  1075. removeAccessData(MA);
  1076. Parent.removeAccessData(MA);
  1077. }
  1078. }
  1079. llvm::erase_if(MemAccs, Predicate);
  1080. InstructionToAccess.erase(MA->getAccessInstruction());
  1081. }
  1082. void ScopStmt::removeSingleMemoryAccess(MemoryAccess *MA, bool AfterHoisting) {
  1083. if (AfterHoisting) {
  1084. auto MAIt = std::find(MemAccs.begin(), MemAccs.end(), MA);
  1085. assert(MAIt != MemAccs.end());
  1086. MemAccs.erase(MAIt);
  1087. removeAccessData(MA);
  1088. Parent.removeAccessData(MA);
  1089. }
  1090. auto It = InstructionToAccess.find(MA->getAccessInstruction());
  1091. if (It != InstructionToAccess.end()) {
  1092. It->second.remove(MA);
  1093. if (It->second.empty())
  1094. InstructionToAccess.erase(MA->getAccessInstruction());
  1095. }
  1096. }
  1097. MemoryAccess *ScopStmt::ensureValueRead(Value *V) {
  1098. MemoryAccess *Access = lookupInputAccessOf(V);
  1099. if (Access)
  1100. return Access;
  1101. ScopArrayInfo *SAI =
  1102. Parent.getOrCreateScopArrayInfo(V, V->getType(), {}, MemoryKind::Value);
  1103. Access = new MemoryAccess(this, nullptr, MemoryAccess::READ, V, V->getType(),
  1104. true, {}, {}, V, MemoryKind::Value);
  1105. Parent.addAccessFunction(Access);
  1106. Access->buildAccessRelation(SAI);
  1107. addAccess(Access);
  1108. Parent.addAccessData(Access);
  1109. return Access;
  1110. }
  1111. raw_ostream &polly::operator<<(raw_ostream &OS, const ScopStmt &S) {
  1112. S.print(OS, PollyPrintInstructions);
  1113. return OS;
  1114. }
  1115. //===----------------------------------------------------------------------===//
  1116. /// Scop class implement
  1117. void Scop::setContext(isl::set NewContext) {
  1118. Context = NewContext.align_params(Context.get_space());
  1119. }
  1120. namespace {
  1121. /// Remap parameter values but keep AddRecs valid wrt. invariant loads.
  1122. struct SCEVSensitiveParameterRewriter
  1123. : public SCEVRewriteVisitor<SCEVSensitiveParameterRewriter> {
  1124. const ValueToValueMap &VMap;
  1125. public:
  1126. SCEVSensitiveParameterRewriter(const ValueToValueMap &VMap,
  1127. ScalarEvolution &SE)
  1128. : SCEVRewriteVisitor(SE), VMap(VMap) {}
  1129. static const SCEV *rewrite(const SCEV *E, ScalarEvolution &SE,
  1130. const ValueToValueMap &VMap) {
  1131. SCEVSensitiveParameterRewriter SSPR(VMap, SE);
  1132. return SSPR.visit(E);
  1133. }
  1134. const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) {
  1135. auto *Start = visit(E->getStart());
  1136. auto *AddRec = SE.getAddRecExpr(SE.getConstant(E->getType(), 0),
  1137. visit(E->getStepRecurrence(SE)),
  1138. E->getLoop(), SCEV::FlagAnyWrap);
  1139. return SE.getAddExpr(Start, AddRec);
  1140. }
  1141. const SCEV *visitUnknown(const SCEVUnknown *E) {
  1142. if (auto *NewValue = VMap.lookup(E->getValue()))
  1143. return SE.getUnknown(NewValue);
  1144. return E;
  1145. }
  1146. };
  1147. /// Check whether we should remap a SCEV expression.
  1148. struct SCEVFindInsideScop : public SCEVTraversal<SCEVFindInsideScop> {
  1149. const ValueToValueMap &VMap;
  1150. bool FoundInside = false;
  1151. const Scop *S;
  1152. public:
  1153. SCEVFindInsideScop(const ValueToValueMap &VMap, ScalarEvolution &SE,
  1154. const Scop *S)
  1155. : SCEVTraversal(*this), VMap(VMap), S(S) {}
  1156. static bool hasVariant(const SCEV *E, ScalarEvolution &SE,
  1157. const ValueToValueMap &VMap, const Scop *S) {
  1158. SCEVFindInsideScop SFIS(VMap, SE, S);
  1159. SFIS.visitAll(E);
  1160. return SFIS.FoundInside;
  1161. }
  1162. bool follow(const SCEV *E) {
  1163. if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(E)) {
  1164. FoundInside |= S->getRegion().contains(AddRec->getLoop());
  1165. } else if (auto *Unknown = dyn_cast<SCEVUnknown>(E)) {
  1166. if (Instruction *I = dyn_cast<Instruction>(Unknown->getValue()))
  1167. FoundInside |= S->getRegion().contains(I) && !VMap.count(I);
  1168. }
  1169. return !FoundInside;
  1170. }
  1171. bool isDone() { return FoundInside; }
  1172. };
  1173. } // end anonymous namespace
  1174. const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *E) const {
  1175. // Check whether it makes sense to rewrite the SCEV. (ScalarEvolution
  1176. // doesn't like addition between an AddRec and an expression that
  1177. // doesn't have a dominance relationship with it.)
  1178. if (SCEVFindInsideScop::hasVariant(E, *SE, InvEquivClassVMap, this))
  1179. return E;
  1180. // Rewrite SCEV.
  1181. return SCEVSensitiveParameterRewriter::rewrite(E, *SE, InvEquivClassVMap);
  1182. }
  1183. void Scop::createParameterId(const SCEV *Parameter) {
  1184. assert(Parameters.count(Parameter));
  1185. assert(!ParameterIds.count(Parameter));
  1186. std::string ParameterName = "p_" + std::to_string(getNumParams() - 1);
  1187. if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
  1188. Value *Val = ValueParameter->getValue();
  1189. if (UseInstructionNames) {
  1190. // If this parameter references a specific Value and this value has a name
  1191. // we use this name as it is likely to be unique and more useful than just
  1192. // a number.
  1193. if (Val->hasName())
  1194. ParameterName = Val->getName().str();
  1195. else if (LoadInst *LI = dyn_cast<LoadInst>(Val)) {
  1196. auto *LoadOrigin = LI->getPointerOperand()->stripInBoundsOffsets();
  1197. if (LoadOrigin->hasName()) {
  1198. ParameterName += "_loaded_from_";
  1199. ParameterName +=
  1200. LI->getPointerOperand()->stripInBoundsOffsets()->getName();
  1201. }
  1202. }
  1203. }
  1204. ParameterName = getIslCompatibleName("", ParameterName, "");
  1205. }
  1206. isl::id Id = isl::id::alloc(getIslCtx(), ParameterName,
  1207. const_cast<void *>((const void *)Parameter));
  1208. ParameterIds[Parameter] = Id;
  1209. }
  1210. void Scop::addParams(const ParameterSetTy &NewParameters) {
  1211. for (const SCEV *Parameter : NewParameters) {
  1212. // Normalize the SCEV to get the representing element for an invariant load.
  1213. Parameter = extractConstantFactor(Parameter, *SE).second;
  1214. Parameter = getRepresentingInvariantLoadSCEV(Parameter);
  1215. if (Parameters.insert(Parameter))
  1216. createParameterId(Parameter);
  1217. }
  1218. }
  1219. isl::id Scop::getIdForParam(const SCEV *Parameter) const {
  1220. // Normalize the SCEV to get the representing element for an invariant load.
  1221. Parameter = getRepresentingInvariantLoadSCEV(Parameter);
  1222. return ParameterIds.lookup(Parameter);
  1223. }
  1224. bool Scop::isDominatedBy(const DominatorTree &DT, BasicBlock *BB) const {
  1225. return DT.dominates(BB, getEntry());
  1226. }
  1227. void Scop::buildContext() {
  1228. isl::space Space = isl::space::params_alloc(getIslCtx(), 0);
  1229. Context = isl::set::universe(Space);
  1230. InvalidContext = isl::set::empty(Space);
  1231. AssumedContext = isl::set::universe(Space);
  1232. DefinedBehaviorContext = isl::set::universe(Space);
  1233. }
  1234. void Scop::addParameterBounds() {
  1235. unsigned PDim = 0;
  1236. for (auto *Parameter : Parameters) {
  1237. ConstantRange SRange = SE->getSignedRange(Parameter);
  1238. Context = addRangeBoundsToSet(Context, SRange, PDim++, isl::dim::param);
  1239. }
  1240. intersectDefinedBehavior(Context, AS_ASSUMPTION);
  1241. }
  1242. void Scop::realignParams() {
  1243. if (PollyIgnoreParamBounds)
  1244. return;
  1245. // Add all parameters into a common model.
  1246. isl::space Space = getFullParamSpace();
  1247. // Align the parameters of all data structures to the model.
  1248. Context = Context.align_params(Space);
  1249. AssumedContext = AssumedContext.align_params(Space);
  1250. InvalidContext = InvalidContext.align_params(Space);
  1251. // As all parameters are known add bounds to them.
  1252. addParameterBounds();
  1253. for (ScopStmt &Stmt : *this)
  1254. Stmt.realignParams();
  1255. // Simplify the schedule according to the context too.
  1256. Schedule = Schedule.gist_domain_params(getContext());
  1257. // Predictable parameter order is required for JSON imports. Ensure alignment
  1258. // by explicitly calling align_params.
  1259. Schedule = Schedule.align_params(Space);
  1260. }
  1261. static isl::set simplifyAssumptionContext(isl::set AssumptionContext,
  1262. const Scop &S) {
  1263. // If we have modeled all blocks in the SCoP that have side effects we can
  1264. // simplify the context with the constraints that are needed for anything to
  1265. // be executed at all. However, if we have error blocks in the SCoP we already
  1266. // assumed some parameter combinations cannot occur and removed them from the
  1267. // domains, thus we cannot use the remaining domain to simplify the
  1268. // assumptions.
  1269. if (!S.hasErrorBlock()) {
  1270. auto DomainParameters = S.getDomains().params();
  1271. AssumptionContext = AssumptionContext.gist_params(DomainParameters);
  1272. }
  1273. AssumptionContext = AssumptionContext.gist_params(S.getContext());
  1274. return AssumptionContext;
  1275. }
  1276. void Scop::simplifyContexts() {
  1277. // The parameter constraints of the iteration domains give us a set of
  1278. // constraints that need to hold for all cases where at least a single
  1279. // statement iteration is executed in the whole scop. We now simplify the
  1280. // assumed context under the assumption that such constraints hold and at
  1281. // least a single statement iteration is executed. For cases where no
  1282. // statement instances are executed, the assumptions we have taken about
  1283. // the executed code do not matter and can be changed.
  1284. //
  1285. // WARNING: This only holds if the assumptions we have taken do not reduce
  1286. // the set of statement instances that are executed. Otherwise we
  1287. // may run into a case where the iteration domains suggest that
  1288. // for a certain set of parameter constraints no code is executed,
  1289. // but in the original program some computation would have been
  1290. // performed. In such a case, modifying the run-time conditions and
  1291. // possibly influencing the run-time check may cause certain scops
  1292. // to not be executed.
  1293. //
  1294. // Example:
  1295. //
  1296. // When delinearizing the following code:
  1297. //
  1298. // for (long i = 0; i < 100; i++)
  1299. // for (long j = 0; j < m; j++)
  1300. // A[i+p][j] = 1.0;
  1301. //
  1302. // we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
  1303. // otherwise we would access out of bound data. Now, knowing that code is
  1304. // only executed for the case m >= 0, it is sufficient to assume p >= 0.
  1305. AssumedContext = simplifyAssumptionContext(AssumedContext, *this);
  1306. InvalidContext = InvalidContext.align_params(getParamSpace());
  1307. simplify(DefinedBehaviorContext);
  1308. DefinedBehaviorContext = DefinedBehaviorContext.align_params(getParamSpace());
  1309. }
  1310. isl::set Scop::getDomainConditions(const ScopStmt *Stmt) const {
  1311. return getDomainConditions(Stmt->getEntryBlock());
  1312. }
  1313. isl::set Scop::getDomainConditions(BasicBlock *BB) const {
  1314. auto DIt = DomainMap.find(BB);
  1315. if (DIt != DomainMap.end())
  1316. return DIt->getSecond();
  1317. auto &RI = *R.getRegionInfo();
  1318. auto *BBR = RI.getRegionFor(BB);
  1319. while (BBR->getEntry() == BB)
  1320. BBR = BBR->getParent();
  1321. return getDomainConditions(BBR->getEntry());
  1322. }
  1323. Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
  1324. DominatorTree &DT, ScopDetection::DetectionContext &DC,
  1325. OptimizationRemarkEmitter &ORE, int ID)
  1326. : IslCtx(isl_ctx_alloc(), isl_ctx_free), SE(&ScalarEvolution), DT(&DT),
  1327. R(R), name(None), HasSingleExitEdge(R.getExitingBlock()), DC(DC),
  1328. ORE(ORE), Affinator(this, LI), ID(ID) {
  1329. // Options defaults that are different from ISL's.
  1330. isl_options_set_schedule_serialize_sccs(IslCtx.get(), true);
  1331. SmallVector<char *, 8> IslArgv;
  1332. IslArgv.reserve(1 + IslArgs.size());
  1333. // Substitute for program name.
  1334. IslArgv.push_back(const_cast<char *>("-polly-isl-arg"));
  1335. for (std::string &Arg : IslArgs)
  1336. IslArgv.push_back(const_cast<char *>(Arg.c_str()));
  1337. // Abort if unknown argument is passed.
  1338. // Note that "-V" (print isl version) will always call exit(0), so we cannot
  1339. // avoid ISL aborting the program at this point.
  1340. unsigned IslParseFlags = ISL_ARG_ALL;
  1341. isl_ctx_parse_options(IslCtx.get(), IslArgv.size(), IslArgv.data(),
  1342. IslParseFlags);
  1343. if (IslOnErrorAbort)
  1344. isl_options_set_on_error(getIslCtx().get(), ISL_ON_ERROR_ABORT);
  1345. buildContext();
  1346. }
  1347. Scop::~Scop() = default;
  1348. void Scop::removeFromStmtMap(ScopStmt &Stmt) {
  1349. for (Instruction *Inst : Stmt.getInstructions())
  1350. InstStmtMap.erase(Inst);
  1351. if (Stmt.isRegionStmt()) {
  1352. for (BasicBlock *BB : Stmt.getRegion()->blocks()) {
  1353. StmtMap.erase(BB);
  1354. // Skip entry basic block, as its instructions are already deleted as
  1355. // part of the statement's instruction list.
  1356. if (BB == Stmt.getEntryBlock())
  1357. continue;
  1358. for (Instruction &Inst : *BB)
  1359. InstStmtMap.erase(&Inst);
  1360. }
  1361. } else {
  1362. auto StmtMapIt = StmtMap.find(Stmt.getBasicBlock());
  1363. if (StmtMapIt != StmtMap.end())
  1364. StmtMapIt->second.erase(std::remove(StmtMapIt->second.begin(),
  1365. StmtMapIt->second.end(), &Stmt),
  1366. StmtMapIt->second.end());
  1367. for (Instruction *Inst : Stmt.getInstructions())
  1368. InstStmtMap.erase(Inst);
  1369. }
  1370. }
  1371. void Scop::removeStmts(function_ref<bool(ScopStmt &)> ShouldDelete,
  1372. bool AfterHoisting) {
  1373. for (auto StmtIt = Stmts.begin(), StmtEnd = Stmts.end(); StmtIt != StmtEnd;) {
  1374. if (!ShouldDelete(*StmtIt)) {
  1375. StmtIt++;
  1376. continue;
  1377. }
  1378. // Start with removing all of the statement's accesses including erasing it
  1379. // from all maps that are pointing to them.
  1380. // Make a temporary copy because removing MAs invalidates the iterator.
  1381. SmallVector<MemoryAccess *, 16> MAList(StmtIt->begin(), StmtIt->end());
  1382. for (MemoryAccess *MA : MAList)
  1383. StmtIt->removeSingleMemoryAccess(MA, AfterHoisting);
  1384. removeFromStmtMap(*StmtIt);
  1385. StmtIt = Stmts.erase(StmtIt);
  1386. }
  1387. }
  1388. void Scop::removeStmtNotInDomainMap() {
  1389. removeStmts([this](ScopStmt &Stmt) -> bool {
  1390. isl::set Domain = DomainMap.lookup(Stmt.getEntryBlock());
  1391. if (Domain.is_null())
  1392. return true;
  1393. return Domain.is_empty();
  1394. });
  1395. }
  1396. void Scop::simplifySCoP(bool AfterHoisting) {
  1397. removeStmts(
  1398. [AfterHoisting](ScopStmt &Stmt) -> bool {
  1399. // Never delete statements that contain calls to debug functions.
  1400. if (hasDebugCall(&Stmt))
  1401. return false;
  1402. bool RemoveStmt = Stmt.isEmpty();
  1403. // Remove read only statements only after invariant load hoisting.
  1404. if (!RemoveStmt && AfterHoisting) {
  1405. bool OnlyRead = true;
  1406. for (MemoryAccess *MA : Stmt) {
  1407. if (MA->isRead())
  1408. continue;
  1409. OnlyRead = false;
  1410. break;
  1411. }
  1412. RemoveStmt = OnlyRead;
  1413. }
  1414. return RemoveStmt;
  1415. },
  1416. AfterHoisting);
  1417. }
  1418. InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) {
  1419. LoadInst *LInst = dyn_cast<LoadInst>(Val);
  1420. if (!LInst)
  1421. return nullptr;
  1422. if (Value *Rep = InvEquivClassVMap.lookup(LInst))
  1423. LInst = cast<LoadInst>(Rep);
  1424. Type *Ty = LInst->getType();
  1425. const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
  1426. for (auto &IAClass : InvariantEquivClasses) {
  1427. if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
  1428. continue;
  1429. auto &MAs = IAClass.InvariantAccesses;
  1430. for (auto *MA : MAs)
  1431. if (MA->getAccessInstruction() == Val)
  1432. return &IAClass;
  1433. }
  1434. return nullptr;
  1435. }
  1436. ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
  1437. ArrayRef<const SCEV *> Sizes,
  1438. MemoryKind Kind,
  1439. const char *BaseName) {
  1440. assert((BasePtr || BaseName) &&
  1441. "BasePtr and BaseName can not be nullptr at the same time.");
  1442. assert(!(BasePtr && BaseName) && "BaseName is redundant.");
  1443. auto &SAI = BasePtr ? ScopArrayInfoMap[std::make_pair(BasePtr, Kind)]
  1444. : ScopArrayNameMap[BaseName];
  1445. if (!SAI) {
  1446. auto &DL = getFunction().getParent()->getDataLayout();
  1447. SAI.reset(new ScopArrayInfo(BasePtr, ElementType, getIslCtx(), Sizes, Kind,
  1448. DL, this, BaseName));
  1449. ScopArrayInfoSet.insert(SAI.get());
  1450. } else {
  1451. SAI->updateElementType(ElementType);
  1452. // In case of mismatching array sizes, we bail out by setting the run-time
  1453. // context to false.
  1454. if (!SAI->updateSizes(Sizes))
  1455. invalidate(DELINEARIZATION, DebugLoc());
  1456. }
  1457. return SAI.get();
  1458. }
  1459. ScopArrayInfo *Scop::createScopArrayInfo(Type *ElementType,
  1460. const std::string &BaseName,
  1461. const std::vector<unsigned> &Sizes) {
  1462. auto *DimSizeType = Type::getInt64Ty(getSE()->getContext());
  1463. std::vector<const SCEV *> SCEVSizes;
  1464. for (auto size : Sizes)
  1465. if (size)
  1466. SCEVSizes.push_back(getSE()->getConstant(DimSizeType, size, false));
  1467. else
  1468. SCEVSizes.push_back(nullptr);
  1469. auto *SAI = getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes,
  1470. MemoryKind::Array, BaseName.c_str());
  1471. return SAI;
  1472. }
  1473. ScopArrayInfo *Scop::getScopArrayInfoOrNull(Value *BasePtr, MemoryKind Kind) {
  1474. auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
  1475. return SAI;
  1476. }
  1477. ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, MemoryKind Kind) {
  1478. auto *SAI = getScopArrayInfoOrNull(BasePtr, Kind);
  1479. assert(SAI && "No ScopArrayInfo available for this base pointer");
  1480. return SAI;
  1481. }
  1482. std::string Scop::getContextStr() const {
  1483. return stringFromIslObj(getContext());
  1484. }
  1485. std::string Scop::getAssumedContextStr() const {
  1486. assert(!AssumedContext.is_null() && "Assumed context not yet built");
  1487. return stringFromIslObj(AssumedContext);
  1488. }
  1489. std::string Scop::getInvalidContextStr() const {
  1490. return stringFromIslObj(InvalidContext);
  1491. }
  1492. std::string Scop::getNameStr() const {
  1493. std::string ExitName, EntryName;
  1494. std::tie(EntryName, ExitName) = getEntryExitStr();
  1495. return EntryName + "---" + ExitName;
  1496. }
  1497. std::pair<std::string, std::string> Scop::getEntryExitStr() const {
  1498. std::string ExitName, EntryName;
  1499. raw_string_ostream ExitStr(ExitName);
  1500. raw_string_ostream EntryStr(EntryName);
  1501. R.getEntry()->printAsOperand(EntryStr, false);
  1502. EntryStr.str();
  1503. if (R.getExit()) {
  1504. R.getExit()->printAsOperand(ExitStr, false);
  1505. ExitStr.str();
  1506. } else
  1507. ExitName = "FunctionExit";
  1508. return std::make_pair(EntryName, ExitName);
  1509. }
  1510. isl::set Scop::getContext() const { return Context; }
  1511. isl::space Scop::getParamSpace() const { return getContext().get_space(); }
  1512. isl::space Scop::getFullParamSpace() const {
  1513. isl::space Space = isl::space::params_alloc(getIslCtx(), ParameterIds.size());
  1514. unsigned PDim = 0;
  1515. for (const SCEV *Parameter : Parameters) {
  1516. isl::id Id = getIdForParam(Parameter);
  1517. Space = Space.set_dim_id(isl::dim::param, PDim++, Id);
  1518. }
  1519. return Space;
  1520. }
  1521. isl::set Scop::getAssumedContext() const {
  1522. assert(!AssumedContext.is_null() && "Assumed context not yet built");
  1523. return AssumedContext;
  1524. }
  1525. bool Scop::isProfitable(bool ScalarsAreUnprofitable) const {
  1526. if (PollyProcessUnprofitable)
  1527. return true;
  1528. if (isEmpty())
  1529. return false;
  1530. unsigned OptimizableStmtsOrLoops = 0;
  1531. for (auto &Stmt : *this) {
  1532. if (Stmt.getNumIterators() == 0)
  1533. continue;
  1534. bool ContainsArrayAccs = false;
  1535. bool ContainsScalarAccs = false;
  1536. for (auto *MA : Stmt) {
  1537. if (MA->isRead())
  1538. continue;
  1539. ContainsArrayAccs |= MA->isLatestArrayKind();
  1540. ContainsScalarAccs |= MA->isLatestScalarKind();
  1541. }
  1542. if (!ScalarsAreUnprofitable || (ContainsArrayAccs && !ContainsScalarAccs))
  1543. OptimizableStmtsOrLoops += Stmt.getNumIterators();
  1544. }
  1545. return OptimizableStmtsOrLoops > 1;
  1546. }
  1547. bool Scop::hasFeasibleRuntimeContext() const {
  1548. if (Stmts.empty())
  1549. return false;
  1550. isl::set PositiveContext = getAssumedContext();
  1551. isl::set NegativeContext = getInvalidContext();
  1552. PositiveContext = PositiveContext.intersect_params(Context);
  1553. PositiveContext = PositiveContext.intersect_params(getDomains().params());
  1554. return PositiveContext.is_empty().is_false() &&
  1555. PositiveContext.is_subset(NegativeContext).is_false();
  1556. }
  1557. MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) {
  1558. Value *PointerBase = MA->getOriginalBaseAddr();
  1559. auto *PointerBaseInst = dyn_cast<Instruction>(PointerBase);
  1560. if (!PointerBaseInst)
  1561. return nullptr;
  1562. auto *BasePtrStmt = getStmtFor(PointerBaseInst);
  1563. if (!BasePtrStmt)
  1564. return nullptr;
  1565. return BasePtrStmt->getArrayAccessOrNULLFor(PointerBaseInst);
  1566. }
  1567. static std::string toString(AssumptionKind Kind) {
  1568. switch (Kind) {
  1569. case ALIASING:
  1570. return "No-aliasing";
  1571. case INBOUNDS:
  1572. return "Inbounds";
  1573. case WRAPPING:
  1574. return "No-overflows";
  1575. case UNSIGNED:
  1576. return "Signed-unsigned";
  1577. case COMPLEXITY:
  1578. return "Low complexity";
  1579. case PROFITABLE:
  1580. return "Profitable";
  1581. case ERRORBLOCK:
  1582. return "No-error";
  1583. case INFINITELOOP:
  1584. return "Finite loop";
  1585. case INVARIANTLOAD:
  1586. return "Invariant load";
  1587. case DELINEARIZATION:
  1588. return "Delinearization";
  1589. }
  1590. llvm_unreachable("Unknown AssumptionKind!");
  1591. }
  1592. bool Scop::isEffectiveAssumption(isl::set Set, AssumptionSign Sign) {
  1593. if (Sign == AS_ASSUMPTION) {
  1594. if (Context.is_subset(Set))
  1595. return false;
  1596. if (AssumedContext.is_subset(Set))
  1597. return false;
  1598. } else {
  1599. if (Set.is_disjoint(Context))
  1600. return false;
  1601. if (Set.is_subset(InvalidContext))
  1602. return false;
  1603. }
  1604. return true;
  1605. }
  1606. bool Scop::trackAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
  1607. AssumptionSign Sign, BasicBlock *BB) {
  1608. if (PollyRemarksMinimal && !isEffectiveAssumption(Set, Sign))
  1609. return false;
  1610. // Do never emit trivial assumptions as they only clutter the output.
  1611. if (!PollyRemarksMinimal) {
  1612. isl::set Univ;
  1613. if (Sign == AS_ASSUMPTION)
  1614. Univ = isl::set::universe(Set.get_space());
  1615. bool IsTrivial = (Sign == AS_RESTRICTION && Set.is_empty()) ||
  1616. (Sign == AS_ASSUMPTION && Univ.is_equal(Set));
  1617. if (IsTrivial)
  1618. return false;
  1619. }
  1620. switch (Kind) {
  1621. case ALIASING:
  1622. AssumptionsAliasing++;
  1623. break;
  1624. case INBOUNDS:
  1625. AssumptionsInbounds++;
  1626. break;
  1627. case WRAPPING:
  1628. AssumptionsWrapping++;
  1629. break;
  1630. case UNSIGNED:
  1631. AssumptionsUnsigned++;
  1632. break;
  1633. case COMPLEXITY:
  1634. AssumptionsComplexity++;
  1635. break;
  1636. case PROFITABLE:
  1637. AssumptionsUnprofitable++;
  1638. break;
  1639. case ERRORBLOCK:
  1640. AssumptionsErrorBlock++;
  1641. break;
  1642. case INFINITELOOP:
  1643. AssumptionsInfiniteLoop++;
  1644. break;
  1645. case INVARIANTLOAD:
  1646. AssumptionsInvariantLoad++;
  1647. break;
  1648. case DELINEARIZATION:
  1649. AssumptionsDelinearization++;
  1650. break;
  1651. }
  1652. auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t";
  1653. std::string Msg = toString(Kind) + Suffix + stringFromIslObj(Set);
  1654. if (BB)
  1655. ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc, BB)
  1656. << Msg);
  1657. else
  1658. ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc,
  1659. R.getEntry())
  1660. << Msg);
  1661. return true;
  1662. }
  1663. void Scop::addAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
  1664. AssumptionSign Sign, BasicBlock *BB,
  1665. bool RequiresRTC) {
  1666. // Simplify the assumptions/restrictions first.
  1667. Set = Set.gist_params(getContext());
  1668. intersectDefinedBehavior(Set, Sign);
  1669. if (!RequiresRTC)
  1670. return;
  1671. if (!trackAssumption(Kind, Set, Loc, Sign, BB))
  1672. return;
  1673. if (Sign == AS_ASSUMPTION)
  1674. AssumedContext = AssumedContext.intersect(Set).coalesce();
  1675. else
  1676. InvalidContext = InvalidContext.unite(Set).coalesce();
  1677. }
  1678. void Scop::intersectDefinedBehavior(isl::set Set, AssumptionSign Sign) {
  1679. if (DefinedBehaviorContext.is_null())
  1680. return;
  1681. if (Sign == AS_ASSUMPTION)
  1682. DefinedBehaviorContext = DefinedBehaviorContext.intersect(Set);
  1683. else
  1684. DefinedBehaviorContext = DefinedBehaviorContext.subtract(Set);
  1685. // Limit the complexity of the context. If complexity is exceeded, simplify
  1686. // the set and check again.
  1687. if (DefinedBehaviorContext.n_basic_set().release() >
  1688. MaxDisjunktsInDefinedBehaviourContext) {
  1689. simplify(DefinedBehaviorContext);
  1690. if (DefinedBehaviorContext.n_basic_set().release() >
  1691. MaxDisjunktsInDefinedBehaviourContext)
  1692. DefinedBehaviorContext = {};
  1693. }
  1694. }
  1695. void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc, BasicBlock *BB) {
  1696. LLVM_DEBUG(dbgs() << "Invalidate SCoP because of reason " << Kind << "\n");
  1697. addAssumption(Kind, isl::set::empty(getParamSpace()), Loc, AS_ASSUMPTION, BB);
  1698. }
  1699. isl::set Scop::getInvalidContext() const { return InvalidContext; }
  1700. void Scop::printContext(raw_ostream &OS) const {
  1701. OS << "Context:\n";
  1702. OS.indent(4) << Context << "\n";
  1703. OS.indent(4) << "Assumed Context:\n";
  1704. OS.indent(4) << AssumedContext << "\n";
  1705. OS.indent(4) << "Invalid Context:\n";
  1706. OS.indent(4) << InvalidContext << "\n";
  1707. OS.indent(4) << "Defined Behavior Context:\n";
  1708. if (!DefinedBehaviorContext.is_null())
  1709. OS.indent(4) << DefinedBehaviorContext << "\n";
  1710. else
  1711. OS.indent(4) << "<unavailable>\n";
  1712. unsigned Dim = 0;
  1713. for (const SCEV *Parameter : Parameters)
  1714. OS.indent(4) << "p" << Dim++ << ": " << *Parameter << "\n";
  1715. }
  1716. void Scop::printAliasAssumptions(raw_ostream &OS) const {
  1717. int noOfGroups = 0;
  1718. for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
  1719. if (Pair.second.size() == 0)
  1720. noOfGroups += 1;
  1721. else
  1722. noOfGroups += Pair.second.size();
  1723. }
  1724. OS.indent(4) << "Alias Groups (" << noOfGroups << "):\n";
  1725. if (MinMaxAliasGroups.empty()) {
  1726. OS.indent(8) << "n/a\n";
  1727. return;
  1728. }
  1729. for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
  1730. // If the group has no read only accesses print the write accesses.
  1731. if (Pair.second.empty()) {
  1732. OS.indent(8) << "[[";
  1733. for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
  1734. OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
  1735. << ">";
  1736. }
  1737. OS << " ]]\n";
  1738. }
  1739. for (const MinMaxAccessTy &MMAReadOnly : Pair.second) {
  1740. OS.indent(8) << "[[";
  1741. OS << " <" << MMAReadOnly.first << ", " << MMAReadOnly.second << ">";
  1742. for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
  1743. OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
  1744. << ">";
  1745. }
  1746. OS << " ]]\n";
  1747. }
  1748. }
  1749. }
  1750. void Scop::printStatements(raw_ostream &OS, bool PrintInstructions) const {
  1751. OS << "Statements {\n";
  1752. for (const ScopStmt &Stmt : *this) {
  1753. OS.indent(4);
  1754. Stmt.print(OS, PrintInstructions);
  1755. }
  1756. OS.indent(4) << "}\n";
  1757. }
  1758. void Scop::printArrayInfo(raw_ostream &OS) const {
  1759. OS << "Arrays {\n";
  1760. for (auto &Array : arrays())
  1761. Array->print(OS);
  1762. OS.indent(4) << "}\n";
  1763. OS.indent(4) << "Arrays (Bounds as pw_affs) {\n";
  1764. for (auto &Array : arrays())
  1765. Array->print(OS, /* SizeAsPwAff */ true);
  1766. OS.indent(4) << "}\n";
  1767. }
  1768. void Scop::print(raw_ostream &OS, bool PrintInstructions) const {
  1769. OS.indent(4) << "Function: " << getFunction().getName() << "\n";
  1770. OS.indent(4) << "Region: " << getNameStr() << "\n";
  1771. OS.indent(4) << "Max Loop Depth: " << getMaxLoopDepth() << "\n";
  1772. OS.indent(4) << "Invariant Accesses: {\n";
  1773. for (const auto &IAClass : InvariantEquivClasses) {
  1774. const auto &MAs = IAClass.InvariantAccesses;
  1775. if (MAs.empty()) {
  1776. OS.indent(12) << "Class Pointer: " << *IAClass.IdentifyingPointer << "\n";
  1777. } else {
  1778. MAs.front()->print(OS);
  1779. OS.indent(12) << "Execution Context: " << IAClass.ExecutionContext
  1780. << "\n";
  1781. }
  1782. }
  1783. OS.indent(4) << "}\n";
  1784. printContext(OS.indent(4));
  1785. printArrayInfo(OS.indent(4));
  1786. printAliasAssumptions(OS);
  1787. printStatements(OS.indent(4), PrintInstructions);
  1788. }
  1789. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  1790. LLVM_DUMP_METHOD void Scop::dump() const { print(dbgs(), true); }
  1791. #endif
  1792. isl::ctx Scop::getIslCtx() const { return IslCtx.get(); }
  1793. __isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
  1794. bool NonNegative,
  1795. RecordedAssumptionsTy *RecordedAssumptions) {
  1796. // First try to use the SCEVAffinator to generate a piecewise defined
  1797. // affine function from @p E in the context of @p BB. If that tasks becomes to
  1798. // complex the affinator might return a nullptr. In such a case we invalidate
  1799. // the SCoP and return a dummy value. This way we do not need to add error
  1800. // handling code to all users of this function.
  1801. auto PWAC = Affinator.getPwAff(E, BB, RecordedAssumptions);
  1802. if (!PWAC.first.is_null()) {
  1803. // TODO: We could use a heuristic and either use:
  1804. // SCEVAffinator::takeNonNegativeAssumption
  1805. // or
  1806. // SCEVAffinator::interpretAsUnsigned
  1807. // to deal with unsigned or "NonNegative" SCEVs.
  1808. if (NonNegative)
  1809. Affinator.takeNonNegativeAssumption(PWAC, RecordedAssumptions);
  1810. return PWAC;
  1811. }
  1812. auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
  1813. invalidate(COMPLEXITY, DL, BB);
  1814. return Affinator.getPwAff(SE->getZero(E->getType()), BB, RecordedAssumptions);
  1815. }
  1816. isl::union_set Scop::getDomains() const {
  1817. isl_space *EmptySpace = isl_space_params_alloc(getIslCtx().get(), 0);
  1818. isl_union_set *Domain = isl_union_set_empty(EmptySpace);
  1819. for (const ScopStmt &Stmt : *this)
  1820. Domain = isl_union_set_add_set(Domain, Stmt.getDomain().release());
  1821. return isl::manage(Domain);
  1822. }
  1823. isl::pw_aff Scop::getPwAffOnly(const SCEV *E, BasicBlock *BB,
  1824. RecordedAssumptionsTy *RecordedAssumptions) {
  1825. PWACtx PWAC = getPwAff(E, BB, RecordedAssumptions);
  1826. return PWAC.first;
  1827. }
  1828. isl::union_map
  1829. Scop::getAccessesOfType(std::function<bool(MemoryAccess &)> Predicate) {
  1830. isl::union_map Accesses = isl::union_map::empty(getIslCtx());
  1831. for (ScopStmt &Stmt : *this) {
  1832. for (MemoryAccess *MA : Stmt) {
  1833. if (!Predicate(*MA))
  1834. continue;
  1835. isl::set Domain = Stmt.getDomain();
  1836. isl::map AccessDomain = MA->getAccessRelation();
  1837. AccessDomain = AccessDomain.intersect_domain(Domain);
  1838. Accesses = Accesses.unite(AccessDomain);
  1839. }
  1840. }
  1841. return Accesses.coalesce();
  1842. }
  1843. isl::union_map Scop::getMustWrites() {
  1844. return getAccessesOfType([](MemoryAccess &MA) { return MA.isMustWrite(); });
  1845. }
  1846. isl::union_map Scop::getMayWrites() {
  1847. return getAccessesOfType([](MemoryAccess &MA) { return MA.isMayWrite(); });
  1848. }
  1849. isl::union_map Scop::getWrites() {
  1850. return getAccessesOfType([](MemoryAccess &MA) { return MA.isWrite(); });
  1851. }
  1852. isl::union_map Scop::getReads() {
  1853. return getAccessesOfType([](MemoryAccess &MA) { return MA.isRead(); });
  1854. }
  1855. isl::union_map Scop::getAccesses() {
  1856. return getAccessesOfType([](MemoryAccess &MA) { return true; });
  1857. }
  1858. isl::union_map Scop::getAccesses(ScopArrayInfo *Array) {
  1859. return getAccessesOfType(
  1860. [Array](MemoryAccess &MA) { return MA.getScopArrayInfo() == Array; });
  1861. }
  1862. isl::union_map Scop::getSchedule() const {
  1863. auto Tree = getScheduleTree();
  1864. return Tree.get_map();
  1865. }
  1866. isl::schedule Scop::getScheduleTree() const {
  1867. return Schedule.intersect_domain(getDomains());
  1868. }
  1869. void Scop::setSchedule(isl::union_map NewSchedule) {
  1870. auto S = isl::schedule::from_domain(getDomains());
  1871. Schedule = S.insert_partial_schedule(
  1872. isl::multi_union_pw_aff::from_union_map(NewSchedule));
  1873. ScheduleModified = true;
  1874. }
  1875. void Scop::setScheduleTree(isl::schedule NewSchedule) {
  1876. Schedule = NewSchedule;
  1877. ScheduleModified = true;
  1878. }
  1879. bool Scop::restrictDomains(isl::union_set Domain) {
  1880. bool Changed = false;
  1881. for (ScopStmt &Stmt : *this) {
  1882. isl::union_set StmtDomain = isl::union_set(Stmt.getDomain());
  1883. isl::union_set NewStmtDomain = StmtDomain.intersect(Domain);
  1884. if (StmtDomain.is_subset(NewStmtDomain))
  1885. continue;
  1886. Changed = true;
  1887. NewStmtDomain = NewStmtDomain.coalesce();
  1888. if (NewStmtDomain.is_empty())
  1889. Stmt.restrictDomain(isl::set::empty(Stmt.getDomainSpace()));
  1890. else
  1891. Stmt.restrictDomain(isl::set(NewStmtDomain));
  1892. }
  1893. return Changed;
  1894. }
  1895. ScalarEvolution *Scop::getSE() const { return SE; }
  1896. void Scop::addScopStmt(BasicBlock *BB, StringRef Name, Loop *SurroundingLoop,
  1897. std::vector<Instruction *> Instructions) {
  1898. assert(BB && "Unexpected nullptr!");
  1899. Stmts.emplace_back(*this, *BB, Name, SurroundingLoop, Instructions);
  1900. auto *Stmt = &Stmts.back();
  1901. StmtMap[BB].push_back(Stmt);
  1902. for (Instruction *Inst : Instructions) {
  1903. assert(!InstStmtMap.count(Inst) &&
  1904. "Unexpected statement corresponding to the instruction.");
  1905. InstStmtMap[Inst] = Stmt;
  1906. }
  1907. }
  1908. void Scop::addScopStmt(Region *R, StringRef Name, Loop *SurroundingLoop,
  1909. std::vector<Instruction *> Instructions) {
  1910. assert(R && "Unexpected nullptr!");
  1911. Stmts.emplace_back(*this, *R, Name, SurroundingLoop, Instructions);
  1912. auto *Stmt = &Stmts.back();
  1913. for (Instruction *Inst : Instructions) {
  1914. assert(!InstStmtMap.count(Inst) &&
  1915. "Unexpected statement corresponding to the instruction.");
  1916. InstStmtMap[Inst] = Stmt;
  1917. }
  1918. for (BasicBlock *BB : R->blocks()) {
  1919. StmtMap[BB].push_back(Stmt);
  1920. if (BB == R->getEntry())
  1921. continue;
  1922. for (Instruction &Inst : *BB) {
  1923. assert(!InstStmtMap.count(&Inst) &&
  1924. "Unexpected statement corresponding to the instruction.");
  1925. InstStmtMap[&Inst] = Stmt;
  1926. }
  1927. }
  1928. }
  1929. ScopStmt *Scop::addScopStmt(isl::map SourceRel, isl::map TargetRel,
  1930. isl::set Domain) {
  1931. #ifndef NDEBUG
  1932. isl::set SourceDomain = SourceRel.domain();
  1933. isl::set TargetDomain = TargetRel.domain();
  1934. assert(Domain.is_subset(TargetDomain) &&
  1935. "Target access not defined for complete statement domain");
  1936. assert(Domain.is_subset(SourceDomain) &&
  1937. "Source access not defined for complete statement domain");
  1938. #endif
  1939. Stmts.emplace_back(*this, SourceRel, TargetRel, Domain);
  1940. CopyStmtsNum++;
  1941. return &(Stmts.back());
  1942. }
  1943. ArrayRef<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {
  1944. auto StmtMapIt = StmtMap.find(BB);
  1945. if (StmtMapIt == StmtMap.end())
  1946. return {};
  1947. return StmtMapIt->second;
  1948. }
  1949. ScopStmt *Scop::getIncomingStmtFor(const Use &U) const {
  1950. auto *PHI = cast<PHINode>(U.getUser());
  1951. BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
  1952. // If the value is a non-synthesizable from the incoming block, use the
  1953. // statement that contains it as user statement.
  1954. if (auto *IncomingInst = dyn_cast<Instruction>(U.get())) {
  1955. if (IncomingInst->getParent() == IncomingBB) {
  1956. if (ScopStmt *IncomingStmt = getStmtFor(IncomingInst))
  1957. return IncomingStmt;
  1958. }
  1959. }
  1960. // Otherwise, use the epilogue/last statement.
  1961. return getLastStmtFor(IncomingBB);
  1962. }
  1963. ScopStmt *Scop::getLastStmtFor(BasicBlock *BB) const {
  1964. ArrayRef<ScopStmt *> StmtList = getStmtListFor(BB);
  1965. if (!StmtList.empty())
  1966. return StmtList.back();
  1967. return nullptr;
  1968. }
  1969. ArrayRef<ScopStmt *> Scop::getStmtListFor(RegionNode *RN) const {
  1970. if (RN->isSubRegion())
  1971. return getStmtListFor(RN->getNodeAs<Region>());
  1972. return getStmtListFor(RN->getNodeAs<BasicBlock>());
  1973. }
  1974. ArrayRef<ScopStmt *> Scop::getStmtListFor(Region *R) const {
  1975. return getStmtListFor(R->getEntry());
  1976. }
  1977. int Scop::getRelativeLoopDepth(const Loop *L) const {
  1978. if (!L || !R.contains(L))
  1979. return -1;
  1980. // outermostLoopInRegion always returns nullptr for top level regions
  1981. if (R.isTopLevelRegion()) {
  1982. // LoopInfo's depths start at 1, we start at 0
  1983. return L->getLoopDepth() - 1;
  1984. } else {
  1985. Loop *OuterLoop = R.outermostLoopInRegion(const_cast<Loop *>(L));
  1986. assert(OuterLoop);
  1987. return L->getLoopDepth() - OuterLoop->getLoopDepth();
  1988. }
  1989. }
  1990. ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {
  1991. for (auto &SAI : arrays()) {
  1992. if (SAI->getName() == BaseName)
  1993. return SAI;
  1994. }
  1995. return nullptr;
  1996. }
  1997. void Scop::addAccessData(MemoryAccess *Access) {
  1998. const ScopArrayInfo *SAI = Access->getOriginalScopArrayInfo();
  1999. assert(SAI && "can only use after access relations have been constructed");
  2000. if (Access->isOriginalValueKind() && Access->isRead())
  2001. ValueUseAccs[SAI].push_back(Access);
  2002. else if (Access->isOriginalAnyPHIKind() && Access->isWrite())
  2003. PHIIncomingAccs[SAI].push_back(Access);
  2004. }
  2005. void Scop::removeAccessData(MemoryAccess *Access) {
  2006. if (Access->isOriginalValueKind() && Access->isWrite()) {
  2007. ValueDefAccs.erase(Access->getAccessValue());
  2008. } else if (Access->isOriginalValueKind() && Access->isRead()) {
  2009. auto &Uses = ValueUseAccs[Access->getScopArrayInfo()];
  2010. auto NewEnd = std::remove(Uses.begin(), Uses.end(), Access);
  2011. Uses.erase(NewEnd, Uses.end());
  2012. } else if (Access->isOriginalPHIKind() && Access->isRead()) {
  2013. PHINode *PHI = cast<PHINode>(Access->getAccessInstruction());
  2014. PHIReadAccs.erase(PHI);
  2015. } else if (Access->isOriginalAnyPHIKind() && Access->isWrite()) {
  2016. auto &Incomings = PHIIncomingAccs[Access->getScopArrayInfo()];
  2017. auto NewEnd = std::remove(Incomings.begin(), Incomings.end(), Access);
  2018. Incomings.erase(NewEnd, Incomings.end());
  2019. }
  2020. }
  2021. MemoryAccess *Scop::getValueDef(const ScopArrayInfo *SAI) const {
  2022. assert(SAI->isValueKind());
  2023. Instruction *Val = dyn_cast<Instruction>(SAI->getBasePtr());
  2024. if (!Val)
  2025. return nullptr;
  2026. return ValueDefAccs.lookup(Val);
  2027. }
  2028. ArrayRef<MemoryAccess *> Scop::getValueUses(const ScopArrayInfo *SAI) const {
  2029. assert(SAI->isValueKind());
  2030. auto It = ValueUseAccs.find(SAI);
  2031. if (It == ValueUseAccs.end())
  2032. return {};
  2033. return It->second;
  2034. }
  2035. MemoryAccess *Scop::getPHIRead(const ScopArrayInfo *SAI) const {
  2036. assert(SAI->isPHIKind() || SAI->isExitPHIKind());
  2037. if (SAI->isExitPHIKind())
  2038. return nullptr;
  2039. PHINode *PHI = cast<PHINode>(SAI->getBasePtr());
  2040. return PHIReadAccs.lookup(PHI);
  2041. }
  2042. ArrayRef<MemoryAccess *> Scop::getPHIIncomings(const ScopArrayInfo *SAI) const {
  2043. assert(SAI->isPHIKind() || SAI->isExitPHIKind());
  2044. auto It = PHIIncomingAccs.find(SAI);
  2045. if (It == PHIIncomingAccs.end())
  2046. return {};
  2047. return It->second;
  2048. }
  2049. bool Scop::isEscaping(Instruction *Inst) {
  2050. assert(contains(Inst) && "The concept of escaping makes only sense for "
  2051. "values defined inside the SCoP");
  2052. for (Use &Use : Inst->uses()) {
  2053. BasicBlock *UserBB = getUseBlock(Use);
  2054. if (!contains(UserBB))
  2055. return true;
  2056. // When the SCoP region exit needs to be simplified, PHIs in the region exit
  2057. // move to a new basic block such that its incoming blocks are not in the
  2058. // SCoP anymore.
  2059. if (hasSingleExitEdge() && isa<PHINode>(Use.getUser()) &&
  2060. isExit(cast<PHINode>(Use.getUser())->getParent()))
  2061. return true;
  2062. }
  2063. return false;
  2064. }
  2065. void Scop::incrementNumberOfAliasingAssumptions(unsigned step) {
  2066. AssumptionsAliasing += step;
  2067. }
  2068. Scop::ScopStatistics Scop::getStatistics() const {
  2069. ScopStatistics Result;
  2070. #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
  2071. auto LoopStat = ScopDetection::countBeneficialLoops(&R, *SE, *getLI(), 0);
  2072. int NumTotalLoops = LoopStat.NumLoops;
  2073. Result.NumBoxedLoops = getBoxedLoops().size();
  2074. Result.NumAffineLoops = NumTotalLoops - Result.NumBoxedLoops;
  2075. for (const ScopStmt &Stmt : *this) {
  2076. isl::set Domain = Stmt.getDomain().intersect_params(getContext());
  2077. bool IsInLoop = Stmt.getNumIterators() >= 1;
  2078. for (MemoryAccess *MA : Stmt) {
  2079. if (!MA->isWrite())
  2080. continue;
  2081. if (MA->isLatestValueKind()) {
  2082. Result.NumValueWrites += 1;
  2083. if (IsInLoop)
  2084. Result.NumValueWritesInLoops += 1;
  2085. }
  2086. if (MA->isLatestAnyPHIKind()) {
  2087. Result.NumPHIWrites += 1;
  2088. if (IsInLoop)
  2089. Result.NumPHIWritesInLoops += 1;
  2090. }
  2091. isl::set AccSet =
  2092. MA->getAccessRelation().intersect_domain(Domain).range();
  2093. if (AccSet.is_singleton()) {
  2094. Result.NumSingletonWrites += 1;
  2095. if (IsInLoop)
  2096. Result.NumSingletonWritesInLoops += 1;
  2097. }
  2098. }
  2099. }
  2100. #endif
  2101. return Result;
  2102. }
  2103. raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {
  2104. scop.print(OS, PollyPrintInstructions);
  2105. return OS;
  2106. }
  2107. //===----------------------------------------------------------------------===//
  2108. void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
  2109. AU.addRequired<LoopInfoWrapperPass>();
  2110. AU.addRequired<RegionInfoPass>();
  2111. AU.addRequired<DominatorTreeWrapperPass>();
  2112. AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
  2113. AU.addRequiredTransitive<ScopDetectionWrapperPass>();
  2114. AU.addRequired<AAResultsWrapperPass>();
  2115. AU.addRequired<AssumptionCacheTracker>();
  2116. AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
  2117. AU.setPreservesAll();
  2118. }
  2119. void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
  2120. Scop::ScopStatistics ScopStats) {
  2121. assert(Stats.NumLoops == ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops);
  2122. NumScops++;
  2123. NumLoopsInScop += Stats.NumLoops;
  2124. MaxNumLoopsInScop =
  2125. std::max(MaxNumLoopsInScop.getValue(), (unsigned)Stats.NumLoops);
  2126. if (Stats.MaxDepth == 0)
  2127. NumScopsDepthZero++;
  2128. else if (Stats.MaxDepth == 1)
  2129. NumScopsDepthOne++;
  2130. else if (Stats.MaxDepth == 2)
  2131. NumScopsDepthTwo++;
  2132. else if (Stats.MaxDepth == 3)
  2133. NumScopsDepthThree++;
  2134. else if (Stats.MaxDepth == 4)
  2135. NumScopsDepthFour++;
  2136. else if (Stats.MaxDepth == 5)
  2137. NumScopsDepthFive++;
  2138. else
  2139. NumScopsDepthLarger++;
  2140. NumAffineLoops += ScopStats.NumAffineLoops;
  2141. NumBoxedLoops += ScopStats.NumBoxedLoops;
  2142. NumValueWrites += ScopStats.NumValueWrites;
  2143. NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
  2144. NumPHIWrites += ScopStats.NumPHIWrites;
  2145. NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
  2146. NumSingletonWrites += ScopStats.NumSingletonWrites;
  2147. NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
  2148. }
  2149. bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {
  2150. auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
  2151. if (!SD.isMaxRegionInScop(*R))
  2152. return false;
  2153. Function *F = R->getEntry()->getParent();
  2154. auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  2155. auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
  2156. auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  2157. auto const &DL = F->getParent()->getDataLayout();
  2158. auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  2159. auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);
  2160. auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
  2161. ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
  2162. S = SB.getScop(); // take ownership of scop object
  2163. #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
  2164. if (S) {
  2165. ScopDetection::LoopStats Stats =
  2166. ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
  2167. updateLoopCountStatistic(Stats, S->getStatistics());
  2168. }
  2169. #endif
  2170. return false;
  2171. }
  2172. void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {
  2173. if (S)
  2174. S->print(OS, PollyPrintInstructions);
  2175. else
  2176. OS << "Invalid Scop!\n";
  2177. }
  2178. char ScopInfoRegionPass::ID = 0;
  2179. Pass *polly::createScopInfoRegionPassPass() { return new ScopInfoRegionPass(); }
  2180. INITIALIZE_PASS_BEGIN(ScopInfoRegionPass, "polly-scops",
  2181. "Polly - Create polyhedral description of Scops", false,
  2182. false);
  2183. INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
  2184. INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
  2185. INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
  2186. INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
  2187. INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
  2188. INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
  2189. INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
  2190. INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
  2191. "Polly - Create polyhedral description of Scops", false,
  2192. false)
  2193. //===----------------------------------------------------------------------===//
  2194. ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
  2195. LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT,
  2196. AssumptionCache &AC, OptimizationRemarkEmitter &ORE)
  2197. : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC), ORE(ORE) {
  2198. recompute();
  2199. }
  2200. void ScopInfo::recompute() {
  2201. RegionToScopMap.clear();
  2202. /// Create polyhedral description of scops for all the valid regions of a
  2203. /// function.
  2204. for (auto &It : SD) {
  2205. Region *R = const_cast<Region *>(It);
  2206. if (!SD.isMaxRegionInScop(*R))
  2207. continue;
  2208. ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
  2209. std::unique_ptr<Scop> S = SB.getScop();
  2210. if (!S)
  2211. continue;
  2212. #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
  2213. ScopDetection::LoopStats Stats =
  2214. ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
  2215. updateLoopCountStatistic(Stats, S->getStatistics());
  2216. #endif
  2217. bool Inserted = RegionToScopMap.insert({R, std::move(S)}).second;
  2218. assert(Inserted && "Building Scop for the same region twice!");
  2219. (void)Inserted;
  2220. }
  2221. }
  2222. bool ScopInfo::invalidate(Function &F, const PreservedAnalyses &PA,
  2223. FunctionAnalysisManager::Invalidator &Inv) {
  2224. // Check whether the analysis, all analyses on functions have been preserved
  2225. // or anything we're holding references to is being invalidated
  2226. auto PAC = PA.getChecker<ScopInfoAnalysis>();
  2227. return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
  2228. Inv.invalidate<ScopAnalysis>(F, PA) ||
  2229. Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
  2230. Inv.invalidate<LoopAnalysis>(F, PA) ||
  2231. Inv.invalidate<AAManager>(F, PA) ||
  2232. Inv.invalidate<DominatorTreeAnalysis>(F, PA) ||
  2233. Inv.invalidate<AssumptionAnalysis>(F, PA);
  2234. }
  2235. AnalysisKey ScopInfoAnalysis::Key;
  2236. ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F,
  2237. FunctionAnalysisManager &FAM) {
  2238. auto &SD = FAM.getResult<ScopAnalysis>(F);
  2239. auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
  2240. auto &LI = FAM.getResult<LoopAnalysis>(F);
  2241. auto &AA = FAM.getResult<AAManager>(F);
  2242. auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
  2243. auto &AC = FAM.getResult<AssumptionAnalysis>(F);
  2244. auto &DL = F.getParent()->getDataLayout();
  2245. auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
  2246. return {DL, SD, SE, LI, AA, DT, AC, ORE};
  2247. }
  2248. PreservedAnalyses ScopInfoPrinterPass::run(Function &F,
  2249. FunctionAnalysisManager &FAM) {
  2250. auto &SI = FAM.getResult<ScopInfoAnalysis>(F);
  2251. // Since the legacy PM processes Scops in bottom up, we print them in reverse
  2252. // order here to keep the output persistent
  2253. for (auto &It : reverse(SI)) {
  2254. if (It.second)
  2255. It.second->print(Stream, PollyPrintInstructions);
  2256. else
  2257. Stream << "Invalid Scop!\n";
  2258. }
  2259. return PreservedAnalyses::all();
  2260. }
  2261. void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
  2262. AU.addRequired<LoopInfoWrapperPass>();
  2263. AU.addRequired<RegionInfoPass>();
  2264. AU.addRequired<DominatorTreeWrapperPass>();
  2265. AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
  2266. AU.addRequiredTransitive<ScopDetectionWrapperPass>();
  2267. AU.addRequired<AAResultsWrapperPass>();
  2268. AU.addRequired<AssumptionCacheTracker>();
  2269. AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
  2270. AU.setPreservesAll();
  2271. }
  2272. bool ScopInfoWrapperPass::runOnFunction(Function &F) {
  2273. auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
  2274. auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  2275. auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
  2276. auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  2277. auto const &DL = F.getParent()->getDataLayout();
  2278. auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  2279. auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
  2280. auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
  2281. Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC, ORE});
  2282. return false;
  2283. }
  2284. void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
  2285. for (auto &It : *Result) {
  2286. if (It.second)
  2287. It.second->print(OS, PollyPrintInstructions);
  2288. else
  2289. OS << "Invalid Scop!\n";
  2290. }
  2291. }
  2292. char ScopInfoWrapperPass::ID = 0;
  2293. Pass *polly::createScopInfoWrapperPassPass() {
  2294. return new ScopInfoWrapperPass();
  2295. }
  2296. INITIALIZE_PASS_BEGIN(
  2297. ScopInfoWrapperPass, "polly-function-scops",
  2298. "Polly - Create polyhedral description of all Scops of a function", false,
  2299. false);
  2300. INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
  2301. INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
  2302. INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
  2303. INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
  2304. INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
  2305. INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
  2306. INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
  2307. INITIALIZE_PASS_END(
  2308. ScopInfoWrapperPass, "polly-function-scops",
  2309. "Polly - Create polyhedral description of all Scops of a function", false,
  2310. false)