-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImplicitLoopBarriers.cpp
More file actions
113 lines (86 loc) · 2.78 KB
/
ImplicitLoopBarriers.cpp
File metadata and controls
113 lines (86 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#define DEBUG_TYPE "mxpa_implicitloopbarriers"
// LLVM
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
// System
#include <iostream>
// MxPA includes
#include "ImplicitLoopBarriers.h"
#include "barrier_inst.h"
#include "triplet_invariance_analysis.h"
namespace SpmdKernel {
using namespace llvm;
namespace Coarsening {
char ImplicitLoopBarriers::ID = 0;
namespace {
static
RegisterPass<ImplicitLoopBarriers> X("implicit-loop-barriers",
"Adds implicit barriers to loops");
}
void
ImplicitLoopBarriers::getAnalysisUsage(AnalysisUsage &AU) const
{
AU.addRequired<DominatorTree>();
AU.addPreserved<DominatorTree>();
AU.addRequired<TripletInvarianceAnalysis>();
AU.addPreserved<TripletInvarianceAnalysis>();
}
bool
ImplicitLoopBarriers::runOnLoop(Loop *L, LPPassManager &LPM)
{
//if (!Workgroup::isKernelToProcess(*L->getHeader()->getParent()))
// return false;
Function *F = L->getExitingBlock()->getParent();
TripletInvarianceAnalysis &TIA =
getAnalysis<TripletInvarianceAnalysis>();
return ProcessLoop(L, LPM);
}
bool
ImplicitLoopBarriers::ProcessLoop(Loop *L, LPPassManager &LPM)
{
bool isBLoop = false;
for (Loop::block_iterator i = L->block_begin(), e = L->block_end();
i != e && !isBLoop; ++i) {
for (BasicBlock::iterator j = (*i)->begin(), e = (*i)->end();
j != e; ++j) {
if (isa<BarrierInst>(j)) {
isBLoop = true;
break;
}
}
}
if (isBLoop) return false;
return AddInnerLoopBarrier(L, LPM);
}
bool
ImplicitLoopBarriers::AddInnerLoopBarrier(Loop *L, LPPassManager &LPM)
{
if (L->getSubLoops().size() > 0)
return false;
BasicBlock *brexit = L->getExitingBlock();
if (brexit == NULL) return false; /* Multiple exit points */
BasicBlock *loopEntry = L->getHeader();
if (loopEntry == NULL) return false; /* Multiple entries blocks? */
Function *f = brexit->getParent();
TripletInvarianceAnalysis &TIA =
getAnalysis<TripletInvarianceAnalysis>();
if (!TIA.isUniform(f, loopEntry)) {
return false;
}
BranchInst *br = dyn_cast<BranchInst>(brexit->getTerminator());
if (br && br->isConditional()
&& TIA.isUniform(f, br->getCondition())) {
LLVMContext &LC = br->getParent()->getParent()->getContext();
IntegerType * IntTy = IntegerType::get(LC, 32);
Value *Args = ConstantInt::get(IntTy, 0);
BarrierInst::createBarrier(Args, brexit->getTerminator());
BarrierInst::createBarrier(Args, loopEntry->getFirstNonPHI());
return true;
} else {
}
return false;
}
}
}