Skip to content

Commit acbdd07

Browse files
committed
[DependenceInfo] Compute WAR dependence info using ISL kills. NFC.
When reading code of Dependences::calculateDependences, I noticed that WAR is computed specifically by buildWAR. Given ISL now supports "kills" in approximate dataflow analysis, this patch takes advantage of it. This patch also cleans up a couple lines redundant codes. Patch by bin.narwal <[email protected]> Differential Revision: https://reviews.llvm.org/D66741 llvm-svn: 370396
1 parent b859168 commit acbdd07

File tree

1 file changed

+16
-114
lines changed

1 file changed

+16
-114
lines changed

polly/lib/Analysis/DependenceInfo.cpp

+16-114
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ void Dependences::addPrivatizationDependences() {
288288
static __isl_give isl_union_flow *buildFlow(__isl_keep isl_union_map *Snk,
289289
__isl_keep isl_union_map *Src,
290290
__isl_keep isl_union_map *MaySrc,
291+
__isl_keep isl_union_map *Kill,
291292
__isl_keep isl_schedule *Schedule) {
292293
isl_union_access_info *AI;
293294

@@ -296,6 +297,8 @@ static __isl_give isl_union_flow *buildFlow(__isl_keep isl_union_map *Snk,
296297
AI = isl_union_access_info_set_may_source(AI, isl_union_map_copy(MaySrc));
297298
if (Src)
298299
AI = isl_union_access_info_set_must_source(AI, isl_union_map_copy(Src));
300+
if (Kill)
301+
AI = isl_union_access_info_set_kill(AI, isl_union_map_copy(Kill));
299302
AI = isl_union_access_info_set_schedule(AI, isl_schedule_copy(Schedule));
300303
auto Flow = isl_union_access_info_compute_flow(AI);
301304
LLVM_DEBUG(if (!Flow) dbgs()
@@ -305,106 +308,6 @@ static __isl_give isl_union_flow *buildFlow(__isl_keep isl_union_map *Snk,
305308
return Flow;
306309
}
307310

308-
/// Compute exact WAR dependences
309-
/// We need exact WAR dependences. That is, if there are
310-
/// dependences of the form:
311-
/// must-W2 (sink) <- must-W1 (sink) <- R (source)
312-
/// We wish to generate *ONLY*:
313-
/// { R -> W1 },
314-
/// NOT:
315-
/// { R -> W2, R -> W1 }
316-
///
317-
/// However, in the case of may-writes, we do *not* wish to allow
318-
/// may-writes to block must-writes. This makes sense, since perhaps the
319-
/// may-write will not happen. In that case, the exact dependence will
320-
/// be the (read -> must-write).
321-
/// Example:
322-
/// must-W2 (sink) <- may-W1 (sink) <- R (source)
323-
/// We wish to generate:
324-
/// { R-> W1, R -> W2 }
325-
///
326-
/// We use the fact that may dependences are not allowed to flow
327-
/// through a must source. That way, reads will be stopped by intermediate
328-
/// must-writes.
329-
/// However, may-sources may not interfere with one another. Hence, reads
330-
/// will not block each other from generating dependences.
331-
///
332-
/// Write (Sink) <- MustWrite (Must-Source) <- Read (MaySource) is
333-
/// present, then the dependence
334-
/// { Write <- Read }
335-
/// is not tracked.
336-
///
337-
/// We would like to specify the Must-Write as kills, source as Read
338-
/// and sink as Write.
339-
/// ISL does not have the functionality currently to support "kills".
340-
/// Use the Must-Source as a way to specify "kills".
341-
/// The drawback is that we will have both
342-
/// { Write <- MustWrite, Write <- Read }
343-
///
344-
/// We need to filter this to track only { Write <- Read }.
345-
///
346-
/// Filtering { Write <- Read } from WAROverestimated:
347-
/// --------------------------------------------------
348-
/// isl_union_flow_get_full_may_dependence gives us dependences of the form
349-
/// WAROverestimated = { Read+MustWrite -> [Write -> MemoryAccess]}
350-
///
351-
/// We need to intersect the domain with Read to get only
352-
/// Read dependences.
353-
/// Read = { Read -> MemoryAccess }
354-
///
355-
///
356-
/// 1. Construct:
357-
/// WARMemAccesses = { Read+Write -> [Read+Write -> MemoryAccess] }
358-
/// This takes a Read+Write from WAROverestimated and maps it to the
359-
/// corresponding wrapped memory access from WAROverestimated.
360-
///
361-
/// 2. Apply WARMemAcesses to the domain of WAR Overestimated to give:
362-
/// WAR = { [Read+Write -> MemoryAccess] -> [Write -> MemoryAccess] }
363-
///
364-
/// WAR is in a state where we can intersect with Read, since they
365-
/// have the same structure.
366-
///
367-
/// 3. Intersect this with a wrapped Read. Read is wrapped
368-
/// to ensure the domains look the same.
369-
/// WAR = WAR \intersect (wrapped Read)
370-
/// WAR = { [Read -> MemoryAccesss] -> [Write -> MemoryAccess] }
371-
///
372-
/// 4. Project out the memory access in the domain to get
373-
/// WAR = { Read -> Write }
374-
static isl_union_map *buildWAR(isl_union_map *Write, isl_union_map *MustWrite,
375-
isl_union_map *Read, isl_schedule *Schedule) {
376-
isl_union_flow *Flow = buildFlow(Write, MustWrite, Read, Schedule);
377-
auto *WAROverestimated = isl_union_flow_get_full_may_dependence(Flow);
378-
379-
// 1. Constructing WARMemAccesses
380-
// WarMemAccesses = { Read+Write -> [Write -> MemAccess] }
381-
// Range factor of range product
382-
// { Read+Write -> MemAcesss }
383-
// Domain projection
384-
// { [Read+Write -> MemAccess] -> Read+Write }
385-
// Reverse
386-
// { Read+Write -> [Read+Write -> MemAccess] }
387-
auto WARMemAccesses =
388-
isl_union_map_range_factor_range(isl_union_map_copy(WAROverestimated));
389-
WARMemAccesses = isl_union_map_domain_map(WARMemAccesses);
390-
WARMemAccesses = isl_union_map_reverse(WARMemAccesses);
391-
392-
// 2. Apply to get domain tagged with memory accesses
393-
isl_union_map *WAR =
394-
isl_union_map_apply_domain(WAROverestimated, WARMemAccesses);
395-
396-
// 3. Intersect with Read to extract only reads
397-
auto ReadWrapped = isl_union_map_wrap(isl_union_map_copy(Read));
398-
WAR = isl_union_map_intersect_domain(WAR, ReadWrapped);
399-
400-
// 4. Project out memory accesses to get usual style dependences
401-
WAR = isl_union_map_range_factor_domain(WAR);
402-
WAR = isl_union_map_domain_factor_domain(WAR);
403-
404-
isl_union_flow_free(Flow);
405-
return WAR;
406-
}
407-
408311
void Dependences::calculateDependences(Scop &S) {
409312
isl_union_map *Read, *MustWrite, *MayWrite, *ReductionTagMap;
410313
isl_schedule *Schedule;
@@ -530,44 +433,43 @@ void Dependences::calculateDependences(Scop &S) {
530433
// }
531434
// }
532435

533-
isl_union_flow *Flow = buildFlow(Write, Write, Read, Schedule);
436+
isl_union_flow *Flow = buildFlow(Write, Write, Read, nullptr, Schedule);
534437
StrictWAW = isl_union_flow_get_must_dependence(Flow);
535438
isl_union_flow_free(Flow);
536439

537440
if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
538-
Flow = buildFlow(Read, MustWrite, MayWrite, Schedule);
441+
Flow = buildFlow(Read, MustWrite, MayWrite, nullptr, Schedule);
539442
RAW = isl_union_flow_get_may_dependence(Flow);
540443
isl_union_flow_free(Flow);
541444

542-
Flow = buildFlow(Write, MustWrite, MayWrite, Schedule);
445+
Flow = buildFlow(Write, MustWrite, MayWrite, nullptr, Schedule);
543446
WAW = isl_union_flow_get_may_dependence(Flow);
544447
isl_union_flow_free(Flow);
545448

546-
WAR = buildWAR(Write, MustWrite, Read, Schedule);
547-
isl_union_map_free(Write);
548-
isl_schedule_free(Schedule);
449+
// ISL now supports "kills" in approximate dataflow analysis, we can
450+
// specify the MustWrite as kills, Read as source and Write as sink.
451+
Flow = buildFlow(Write, nullptr, Read, MustWrite, Schedule);
452+
WAR = isl_union_flow_get_may_dependence(Flow);
453+
isl_union_flow_free(Flow);
549454
} else {
550-
isl_union_flow *Flow;
551-
552-
Flow = buildFlow(Read, nullptr, Write, Schedule);
455+
Flow = buildFlow(Read, nullptr, Write, nullptr, Schedule);
553456
RAW = isl_union_flow_get_may_dependence(Flow);
554457
isl_union_flow_free(Flow);
555458

556-
Flow = buildFlow(Write, nullptr, Read, Schedule);
459+
Flow = buildFlow(Write, nullptr, Read, nullptr, Schedule);
557460
WAR = isl_union_flow_get_may_dependence(Flow);
558461
isl_union_flow_free(Flow);
559462

560-
Flow = buildFlow(Write, nullptr, Write, Schedule);
463+
Flow = buildFlow(Write, nullptr, Write, nullptr, Schedule);
561464
WAW = isl_union_flow_get_may_dependence(Flow);
562465
isl_union_flow_free(Flow);
563-
564-
isl_union_map_free(Write);
565-
isl_schedule_free(Schedule);
566466
}
567467

468+
isl_union_map_free(Write);
568469
isl_union_map_free(MustWrite);
569470
isl_union_map_free(MayWrite);
570471
isl_union_map_free(Read);
472+
isl_schedule_free(Schedule);
571473

572474
RAW = isl_union_map_coalesce(RAW);
573475
WAW = isl_union_map_coalesce(WAW);

0 commit comments

Comments
 (0)