# Changeset View

# Standalone View

# lib/Analysis/ScopInfo.cpp

Show First 20 Lines • Show All 103 Lines • ▼ Show 20 Line(s) | 103 | STATISTIC( | |||
---|---|---|---|---|---|

104 | NumValueWritesInLoops, | 104 | NumValueWritesInLoops, | ||

105 | "Number of scalar value writes nested in affine loops after ScopInfo"); | 105 | "Number of scalar value writes nested in affine loops after ScopInfo"); | ||

106 | STATISTIC(NumPHIWrites, "Number of scalar phi writes after ScopInfo"); | 106 | STATISTIC(NumPHIWrites, "Number of scalar phi writes after ScopInfo"); | ||

107 | STATISTIC(NumPHIWritesInLoops, | 107 | STATISTIC(NumPHIWritesInLoops, | ||

108 | "Number of scalar phi writes nested in affine loops after ScopInfo"); | 108 | "Number of scalar phi writes nested in affine loops after ScopInfo"); | ||

109 | STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo"); | 109 | STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo"); | ||

110 | STATISTIC(NumSingletonWritesInLoops, | 110 | STATISTIC(NumSingletonWritesInLoops, | ||

111 | "Number of singleton writes nested in affine loops after ScopInfo"); | 111 | "Number of singleton writes nested in affine loops after ScopInfo"); | ||

112 | STATISTIC(AssumptionsAvoidSingleIter, | ||||

113 | "Number of assumptions to skip singletons in statement domains."); | ||||

112 | 114 | | |||

113 | int const polly::MaxDisjunctsInDomain = 20; | 115 | int const polly::MaxDisjunctsInDomain = 20; | ||

114 | 116 | | |||

115 | // The number of disjunct in the context after which we stop to add more | 117 | // The number of disjunct in the context after which we stop to add more | ||

116 | // disjuncts. This parameter is there to avoid exponential growth in the | 118 | // disjuncts. This parameter is there to avoid exponential growth in the | ||

117 | // number of disjunct when adding non-convex sets to the context. | 119 | // number of disjunct when adding non-convex sets to the context. | ||

118 | static int const MaxDisjunctsInContext = 4; | 120 | static int const MaxDisjunctsInContext = 4; | ||

119 | 121 | | |||

▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Line(s) | 184 | static cl::opt<bool, true> XUseInstructionNames( | |||

184 | cl::desc("Use LLVM-IR names when deriving statement names"), | 186 | cl::desc("Use LLVM-IR names when deriving statement names"), | ||

185 | cl::location(UseInstructionNames), cl::Hidden, cl::init(false), | 187 | cl::location(UseInstructionNames), cl::Hidden, cl::init(false), | ||

186 | cl::ZeroOrMore, cl::cat(PollyCategory)); | 188 | cl::ZeroOrMore, cl::cat(PollyCategory)); | ||

187 | 189 | | |||

188 | static cl::opt<bool> PollyPrintInstructions( | 190 | static cl::opt<bool> PollyPrintInstructions( | ||

189 | "polly-print-instructions", cl::desc("Output instructions per ScopStmt"), | 191 | "polly-print-instructions", cl::desc("Output instructions per ScopStmt"), | ||

190 | cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory)); | 192 | cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory)); | ||

191 | 193 | | |||

194 | static cl::opt<bool> | ||||

195 | HandleDoWhile("polly-avoid-singular-loops", | ||||

Meinersbur: Can you explain the why you chose the name `model-do-while`? | |||||

Done ReplyThe problem with disjunction in domains is very common in *do while* style loops where the domain of the statement has either one iteration (if the loop condition is false) or more than one. The idea in this patch is that if the loop condition is actually false we should really not try to run the transformed version of the loop anyway since it not beneficial for a loop of 1 iteration. I am open t other names if you have suggestions :) sabuasal: The problem with disjunction in domains is very common in *do while* style loops where the… | |||||

Not Done ReplyThe problem I see is that this does not only apply to do-while loops (which is a syntactical element), but e.g. to loop-rotated other loops as well. [suggestion] (in compiler lingo, 'assume' usually means the compiler is free to use the fact for optimization without requiring it to be verified, 'expect' that violating the fact must still result in correct code). Meinersbur: The problem I see is that this does not only apply to do-while loops (which is a syntactical… | |||||

Done ReplyYou are right, it does happen with rotated loops. It iis actually why it was significant enough that I figured we could model it in polly. I'll use polly-avoid-singular-loops. sabuasal: You are right, it does happen with rotated loops. It iis actually why it was significant enough… | |||||

196 | cl::desc("Prune exeution domain of statements to ignore" | ||||

197 | " disjunction sets that only have one instance"), | ||||

198 | cl::Hidden, cl::ZeroOrMore, cl::init(false), | ||||

199 | cl::cat(PollyCategory)); | ||||

192 | //===----------------------------------------------------------------------===// | 200 | //===----------------------------------------------------------------------===// | ||

193 | 201 | | |||

194 | // Create a sequence of two schedules. Either argument may be null and is | 202 | // Create a sequence of two schedules. Either argument may be null and is | ||

195 | // interpreted as the empty schedule. Can also return null if both schedules are | 203 | // interpreted as the empty schedule. Can also return null if both schedules are | ||

196 | // empty. | 204 | // empty. | ||

197 | static isl::schedule combineInSequence(isl::schedule Prev, isl::schedule Succ) { | 205 | static isl::schedule combineInSequence(isl::schedule Prev, isl::schedule Succ) { | ||

198 | if (!Prev) | 206 | if (!Prev) | ||

199 | return Succ; | 207 | return Succ; | ||

▲ Show 20 Lines • Show All 999 Lines • ▼ Show 20 Line(s) | 1206 | if (Schedule.is_empty()) | |||

1199 | return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace()))); | 1207 | return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace()))); | ||

1200 | isl::map M = M.from_union_map(Schedule); | 1208 | isl::map M = M.from_union_map(Schedule); | ||

1201 | M = M.coalesce(); | 1209 | M = M.coalesce(); | ||

1202 | M = M.gist_domain(Domain); | 1210 | M = M.gist_domain(Domain); | ||

1203 | M = M.coalesce(); | 1211 | M = M.coalesce(); | ||

1204 | return M; | 1212 | return M; | ||

1205 | } | 1213 | } | ||

1206 | 1214 | | |||

1215 | void ScopStmt::setDomain(isl::set NewDomain) { Domain = NewDomain; } | ||||

Done Reply
Meinersbur: `setDomain` would better describe what this function does. | |||||

1216 | | ||||

1207 | void ScopStmt::restrictDomain(isl::set NewDomain) { | 1217 | void ScopStmt::restrictDomain(isl::set NewDomain) { | ||

1208 | assert(NewDomain.is_subset(Domain) && | 1218 | assert(NewDomain.is_subset(Domain) && | ||

1209 | "New domain is not a subset of old domain!"); | 1219 | "New domain is not a subset of old domain!"); | ||

1210 | Domain = NewDomain; | 1220 | Domain = NewDomain; | ||

1211 | } | 1221 | } | ||

1212 | 1222 | | |||

1213 | void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) { | 1223 | void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) { | ||

1214 | Instruction *AccessInst = Access->getAccessInstruction(); | 1224 | Instruction *AccessInst = Access->getAccessInstruction(); | ||

▲ Show 20 Lines • Show All 949 Lines • ▼ Show 20 Line(s) | 2168 | static isl::set simplifyAssumptionContext(isl::set AssumptionContext, | |||

2164 | // domains, thus we cannot use the remaining domain to simplify the | 2174 | // domains, thus we cannot use the remaining domain to simplify the | ||

2165 | // assumptions. | 2175 | // assumptions. | ||

2166 | if (!S.hasErrorBlock()) { | 2176 | if (!S.hasErrorBlock()) { | ||

2167 | auto DomainParameters = S.getDomains().params(); | 2177 | auto DomainParameters = S.getDomains().params(); | ||

2168 | AssumptionContext = AssumptionContext.gist_params(DomainParameters); | 2178 | AssumptionContext = AssumptionContext.gist_params(DomainParameters); | ||

2169 | } | 2179 | } | ||

2170 | 2180 | | |||

2171 | AssumptionContext = AssumptionContext.gist_params(S.getContext()); | 2181 | AssumptionContext = AssumptionContext.gist_params(S.getContext()); | ||

2172 | return AssumptionContext; | 2182 | return AssumptionContext; | ||

Done ReplyNo need to check Meinersbur: No need to check `plain_is_universe()`; intersection with the universe would not change the set. | |||||

2173 | } | 2183 | } | ||

2174 | 2184 | | |||

Not Done Reply[serious] Meinersbur: [serious] `simplifyAssumptionContext` should not logically modify the `AssumptionContext`. The… | |||||

Done ReplyActually, this has to be done after simplification. The AssumptionContext is simplified (gisted-ed) with the domain parameters as you can see in line 2178. If you look at line 3025 you'll see that we also gist the domain parameters with the RestrictDomainParameters we are building. this can result in a situation where the parameters restriction we add can be completely removed from both the assumption, and hence the runtime check, and the materialized domain. the reason it is important to gist the domain parameters is that it we'd rather push all the complex params to the RTC and keep the materialized statement as simple as possible. Can you suggest a better place for the intersection that insures our restriction params are always present in the AssumptionContext? I think intersectBBDomainParams() might work? sabuasal: Actually, this has to be done after simplification. The AssumptionContext is simplified… | |||||

Done ReplyHere is an example from an internal test case that shows the problem: Avoid Single Iter Assumptions: [p_0, p_1, p_2] -> { : p_1 = 1 and p_2 > 0 and (p_0 >= 32 or p_0 <= 30) } Assumed context Before gist with domain params: [p_0, p_1, p_2] -> { : (p_1 = 1 and p_0 >= 32 and p_2 > 0) or (p_1 = 1 and p_0 <= 30 and p_2 > 0) } sabuasal: Here is an example from an internal test case that shows the problem:
Avoid Single Iter… | |||||

2175 | void Scop::simplifyContexts() { | 2185 | void Scop::simplifyContexts() { | ||

2176 | // The parameter constraints of the iteration domains give us a set of | 2186 | // The parameter constraints of the iteration domains give us a set of | ||

2177 | // constraints that need to hold for all cases where at least a single | 2187 | // constraints that need to hold for all cases where at least a single | ||

2178 | // statement iteration is executed in the whole scop. We now simplify the | 2188 | // statement iteration is executed in the whole scop. We now simplify the | ||

2179 | // assumed context under the assumption that such constraints hold and at | 2189 | // assumed context under the assumption that such constraints hold and at | ||

2180 | // least a single statement iteration is executed. For cases where no | 2190 | // least a single statement iteration is executed. For cases where no | ||

2181 | // statement instances are executed, the assumptions we have taken about | 2191 | // statement instances are executed, the assumptions we have taken about | ||

2182 | // the executed code do not matter and can be changed. | 2192 | // the executed code do not matter and can be changed. | ||

▲ Show 20 Lines • Show All 692 Lines • ▼ Show 20 Line(s) | 2884 | isl::constraint C = | |||

2875 | isl::constraint::alloc_equality(isl::local_space(MapSpace)); | 2885 | isl::constraint::alloc_equality(isl::local_space(MapSpace)); | ||

2876 | C = C.set_constant_si(1); | 2886 | C = C.set_constant_si(1); | ||

2877 | C = C.set_coefficient_si(isl::dim::in, Dim, 1); | 2887 | C = C.set_coefficient_si(isl::dim::in, Dim, 1); | ||

2878 | C = C.set_coefficient_si(isl::dim::out, Dim, -1); | 2888 | C = C.set_coefficient_si(isl::dim::out, Dim, -1); | ||

2879 | NextIterationMap = NextIterationMap.add_constraint(C); | 2889 | NextIterationMap = NextIterationMap.add_constraint(C); | ||

2880 | return NextIterationMap; | 2890 | return NextIterationMap; | ||

2881 | } | 2891 | } | ||

2882 | 2892 | | |||

2893 | /// Check if the execution domain represented in the @p Set | ||||

Not Done ReplyPlease document/doxygen what this function is doing Meinersbur: Please document/doxygen what this function is doing | |||||

Done Replywill do. sabuasal: will do. | |||||

2894 | /// is a singleton. | ||||

2895 | /// This method also check multi dimensional schedules for | ||||

2896 | /// the existence of Singleton by projecting out all but one | ||||

2897 | /// dimension each time. | ||||

2898 | static bool hasSingleton(isl::set Set) { | ||||

2899 | if (Set.is_singleton()) | ||||

2900 | return true; | ||||

2901 | int Dims = Set.dim(isl::dim::set); | ||||

2902 | for (int i = 0; i < Dims; i++) { | ||||

Done ReplyCondition not necessary: project_out will not do anything when projecting-out zero dimensions. Meinersbur: Condition not necessary: project_out will not do anything when projecting-out zero dimensions. | |||||

Done Replywill do. sabuasal: will do. | |||||

2903 | // project out all dimensions that are not this dimension. | ||||

2904 | isl::set DimOnly = Set; | ||||

2905 | if (i > 0) // Remove left dimensions. | ||||

MeinersburUnsubmitted Not Done ReplyCondition is unnecessay: Meinersbur: Condition is unnecessay: `.project_out(isl::dim::set, 0, 0)` will just return the original set. | |||||

2906 | DimOnly = DimOnly.project_out(isl::dim::set, 0, i); | ||||

2907 | // Remove right dimensions. | ||||

2908 | DimOnly = DimOnly.project_out(isl::dim::set, 1, Dims - i - 1); | ||||

2909 | if (DimOnly.is_singleton()) { | ||||

2910 | LLVM_DEBUG(dbgs() << "Found Singleton in Dim: " << i << " "; | ||||

2911 | DimOnly.dump(); | ||||

2912 | dbgs() << "\n";); | ||||

2913 | return true; | ||||

2914 | } | ||||

2915 | } | ||||

2916 | return false; | ||||

2917 | } | ||||

2918 | | ||||

2883 | bool Scop::addLoopBoundsToHeaderDomain( | 2919 | bool Scop::addLoopBoundsToHeaderDomain( | ||

2884 | Loop *L, LoopInfo &LI, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { | 2920 | Loop *L, LoopInfo &LI, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { | ||

2885 | int LoopDepth = getRelativeLoopDepth(L); | 2921 | int LoopDepth = getRelativeLoopDepth(L); | ||

2886 | assert(LoopDepth >= 0 && "Loop in region should have at least depth one"); | 2922 | assert(LoopDepth >= 0 && "Loop in region should have at least depth one"); | ||

2887 | 2923 | | |||

2888 | BasicBlock *HeaderBB = L->getHeader(); | 2924 | BasicBlock *HeaderBB = L->getHeader(); | ||

2889 | assert(DomainMap.count(HeaderBB)); | 2925 | assert(DomainMap.count(HeaderBB)); | ||

2890 | isl::set &HeaderBBDom = DomainMap[HeaderBB]; | 2926 | isl::set &HeaderBBDom = DomainMap[HeaderBB]; | ||

▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | |||||

2954 | if (Affinator.hasNSWAddRecForLoop(L)) | 2990 | if (Affinator.hasNSWAddRecForLoop(L)) | ||

2955 | return true; | 2991 | return true; | ||

2956 | 2992 | | |||

2957 | isl::set UnboundedCtx = Parts.first.params(); | 2993 | isl::set UnboundedCtx = Parts.first.params(); | ||

2958 | recordAssumption(INFINITELOOP, UnboundedCtx, | 2994 | recordAssumption(INFINITELOOP, UnboundedCtx, | ||

2959 | HeaderBB->getTerminator()->getDebugLoc(), AS_RESTRICTION); | 2995 | HeaderBB->getTerminator()->getDebugLoc(), AS_RESTRICTION); | ||

2960 | return true; | 2996 | return true; | ||

2961 | } | 2997 | } | ||

2962 | 2998 | | |||

Not Done Reply[serious] Instead of for (int i = 0; i < -n; i+=1) Stmt(i); What is the reason for this logic to be in Meinersbur: [serious] Instead of `lexmax` on the scatter function, shouldn't we subtract the parameter… | |||||

Done ReplyThanks for the suggestion here, I think this could actually fit in intersectBBDomainParams(), let me experiment with it. sabuasal: Thanks for the suggestion here, I think this could actually fit in intersectBBDomainParams()… | |||||

2999 | void Scop::ignoreSingleIterationDomains() { | ||||

Not Done ReplyWe are trying to move the functionality that is only required for the construction of a SCoP into ScopBuilder. Meinersbur: We are trying to move the functionality that is only required for the construction of a SCoP… | |||||

Not Done ReplyAny reasons to not move this to Meinersbur: Any reasons to not move this to `ScopBuilder`? | |||||

3000 | if (!HandleDoWhile) | ||||

3001 | return; | ||||

3002 | for (ScopStmt &Stmt : *this) { | ||||

3003 | bool FoundSingleton = false; | ||||

3004 | isl::set UpperBoundParams = isl::set::empty(getParamSpace()); | ||||

3005 | isl::set Domain = Stmt.getDomain(); | ||||

3006 | for (isl::basic_set BSet : Domain.get_basic_set_list()) { | ||||

3007 | isl::set Set(BSet); | ||||

MeinersburUnsubmitted Not Done ReplyA Meinersbur: A `basic_set` should convert implicitly to a `set` when passed to `hasSingleton` | |||||

3008 | // Ignore the set that has only one iteration. | ||||

3009 | if (hasSingleton(Set)) { | ||||

3010 | FoundSingleton = true; | ||||

3011 | continue; | ||||

3012 | } | ||||

3013 | UpperBoundParams = UpperBoundParams.unite(BSet.lexmax().params()); | ||||

MeinersburUnsubmitted Not Done Reply[serious] I am quite sure that this method removing the single-iteration-domain is not reliable. Examples include: for (int i = 0; i < -n; i+=1) Stmt(i); if (unsigned i = 0; i < (n%8); i+=1) Stmt(i); and combinations thereof. At least the first would do the exact opposite: Remove all contexts that have more than one iteration. Meinersbur: [serious] I am quite sure that this method removing the single-iteration-domain is not reliable. | |||||

MeinersburUnsubmitted Not Done ReplyWhat I would try to do: InvalidContext = InvalidContext.unite(BSet.params()) This might not directly solve the problem since the invalid context is not used for gisting the iterations space. So the alterntive is to collect the params Meinersbur: What I would try to do:
```
InvalidContext = InvalidContext.unite(BSet.params())
```
This might… | |||||

3014 | } | ||||

3015 | if (!UpperBoundParams.is_empty() && FoundSingleton) { | ||||

3016 | recordAssumption(AVOIDSINGLEITERATION, UpperBoundParams, | ||||

3017 | Stmt.getEntryBlock()->getTerminator()->getDebugLoc(), | ||||

3018 | AS_ASSUMPTION, nullptr); | ||||

3019 | RestrictDomainParams = RestrictDomainParams.intersect(UpperBoundParams); | ||||

3020 | } | ||||

3021 | } | ||||

3022 | if (!RestrictDomainParams.plain_is_universe()) { | ||||

MeinersburUnsubmitted Not Done ReplyIs this a safeguard to avoid excluding everything? Could you write a comment about its intention? Meinersbur: Is this a safeguard to avoid excluding everything? Could you write a comment about its… | |||||

3023 | for (ScopStmt &Stmt : *this) { | ||||

3024 | isl::set Dom = Stmt.getDomain(); | ||||

3025 | isl::set NewDom = Dom.intersect_params(RestrictDomainParams); | ||||

3026 | NewDom = NewDom.coalesce(); | ||||

3027 | NewDom = NewDom.gist_params(RestrictDomainParams); | ||||

3028 | Stmt.setDomain(NewDom); | ||||

3029 | } | ||||

3030 | Schedule = Schedule.gist_domain_params(RestrictDomainParams); | ||||

3031 | } | ||||

3032 | } | ||||

3033 | | ||||

3034 | void Scop::enforceAssumptionsForAvoidsingleIter() { | ||||

3035 | AssumedContext = AssumedContext.intersect(getRestrictDomainParams()); | ||||

MeinersburUnsubmitted Not Done ReplyCould you explain why Meinersbur: Could you explain why `RestrictDomainParams` has to be collected separately from… | |||||

3036 | } | ||||

3037 | | ||||

2963 | MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) { | 3038 | MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) { | ||

2964 | Value *PointerBase = MA->getOriginalBaseAddr(); | 3039 | Value *PointerBase = MA->getOriginalBaseAddr(); | ||

2965 | 3040 | | |||

2966 | auto *PointerBaseInst = dyn_cast<Instruction>(PointerBase); | 3041 | auto *PointerBaseInst = dyn_cast<Instruction>(PointerBase); | ||

2967 | if (!PointerBaseInst) | 3042 | if (!PointerBaseInst) | ||

2968 | return nullptr; | 3043 | return nullptr; | ||

2969 | 3044 | | |||

2970 | auto *BasePtrStmt = getStmtFor(PointerBaseInst); | 3045 | auto *BasePtrStmt = getStmtFor(PointerBaseInst); | ||

▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Line(s) | 3289 | Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI, | |||

3216 | OptimizationRemarkEmitter &ORE) | 3291 | OptimizationRemarkEmitter &ORE) | ||

3217 | : IslCtx(isl_ctx_alloc(), isl_ctx_free), SE(&ScalarEvolution), DT(&DT), | 3292 | : IslCtx(isl_ctx_alloc(), isl_ctx_free), SE(&ScalarEvolution), DT(&DT), | ||

3218 | R(R), name(None), HasSingleExitEdge(R.getExitingBlock()), DC(DC), | 3293 | R(R), name(None), HasSingleExitEdge(R.getExitingBlock()), DC(DC), | ||

3219 | ORE(ORE), Affinator(this, LI), | 3294 | ORE(ORE), Affinator(this, LI), | ||

3220 | ID(getNextID((*R.getEntry()->getParent()).getName().str())) { | 3295 | ID(getNextID((*R.getEntry()->getParent()).getName().str())) { | ||

3221 | if (IslOnErrorAbort) | 3296 | if (IslOnErrorAbort) | ||

3222 | isl_options_set_on_error(getIslCtx().get(), ISL_ON_ERROR_ABORT); | 3297 | isl_options_set_on_error(getIslCtx().get(), ISL_ON_ERROR_ABORT); | ||

3223 | buildContext(); | 3298 | buildContext(); | ||

3299 | RestrictDomainParams = isl::set::universe(getParamSpace()); | ||||

3224 | } | 3300 | } | ||

3225 | 3301 | | |||

3226 | Scop::~Scop() = default; | 3302 | Scop::~Scop() = default; | ||

3227 | 3303 | | |||

3228 | void Scop::foldSizeConstantsToRight() { | 3304 | void Scop::foldSizeConstantsToRight() { | ||

3229 | isl::union_set Accessed = getAccesses().range(); | 3305 | isl::union_set Accessed = getAccesses().range(); | ||

3230 | 3306 | | |||

3231 | for (auto Array : arrays()) { | 3307 | for (auto Array : arrays()) { | ||

▲ Show 20 Lines • Show All 437 Lines • ▼ Show 20 Line(s) | 3731 | static std::string toString(AssumptionKind Kind) { | |||

3669 | case ERRORBLOCK: | 3745 | case ERRORBLOCK: | ||

3670 | return "No-error"; | 3746 | return "No-error"; | ||

3671 | case INFINITELOOP: | 3747 | case INFINITELOOP: | ||

3672 | return "Finite loop"; | 3748 | return "Finite loop"; | ||

3673 | case INVARIANTLOAD: | 3749 | case INVARIANTLOAD: | ||

3674 | return "Invariant load"; | 3750 | return "Invariant load"; | ||

3675 | case DELINEARIZATION: | 3751 | case DELINEARIZATION: | ||

3676 | return "Delinearization"; | 3752 | return "Delinearization"; | ||

3753 | case AVOIDSINGLEITERATION: | ||||

3754 | return "Avoid single iteration in loops"; | ||||

Done Reply[suggestion] A different description such as "Avoid single iteration loops? Meinersbur: [suggestion] A different description such as "Avoid single iteration loops? | |||||

3677 | } | 3755 | } | ||

3678 | llvm_unreachable("Unknown AssumptionKind!"); | 3756 | llvm_unreachable("Unknown AssumptionKind!"); | ||

3679 | } | 3757 | } | ||

3680 | 3758 | | |||

3681 | bool Scop::isEffectiveAssumption(isl::set Set, AssumptionSign Sign) { | 3759 | bool Scop::isEffectiveAssumption(isl::set Set, AssumptionSign Sign) { | ||

3682 | if (Sign == AS_ASSUMPTION) { | 3760 | if (Sign == AS_ASSUMPTION) { | ||

3683 | if (Context.is_subset(Set)) | 3761 | if (Context.is_subset(Set)) | ||

3684 | return false; | 3762 | return false; | ||

▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 3816 | case INFINITELOOP: | |||

3739 | AssumptionsInfiniteLoop++; | 3817 | AssumptionsInfiniteLoop++; | ||

3740 | break; | 3818 | break; | ||

3741 | case INVARIANTLOAD: | 3819 | case INVARIANTLOAD: | ||

3742 | AssumptionsInvariantLoad++; | 3820 | AssumptionsInvariantLoad++; | ||

3743 | break; | 3821 | break; | ||

3744 | case DELINEARIZATION: | 3822 | case DELINEARIZATION: | ||

3745 | AssumptionsDelinearization++; | 3823 | AssumptionsDelinearization++; | ||

3746 | break; | 3824 | break; | ||

3825 | case AVOIDSINGLEITERATION: | ||||

3826 | AssumptionsAvoidSingleIter++; | ||||

3827 | break; | ||||

3747 | } | 3828 | } | ||

3748 | 3829 | | |||

3749 | auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t"; | 3830 | auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t"; | ||

3750 | std::string Msg = toString(Kind) + Suffix + Set.to_str(); | 3831 | std::string Msg = toString(Kind) + Suffix + Set.to_str(); | ||

3751 | if (BB) | 3832 | if (BB) | ||

3752 | ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc, BB) | 3833 | ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc, BB) | ||

3753 | << Msg); | 3834 | << Msg); | ||

3754 | else | 3835 | else | ||

▲ Show 20 Lines • Show All 940 Lines • Show Last 20 Lines |

Can you explain the why you chose the name

model-do-while?