1
// LLVM function pass to canonicalize barriers.
3
// Copyright (c) 2011 Universidad Rey Juan Carlos
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
12
// The above copyright notice and this permission notice shall be included in
13
// all copies or substantial portions of the Software.
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
#include "CanonicalizeBarriers.h"
24
#include "llvm/ADT/SmallString.h"
25
#include "llvm/Instructions.h"
30
#define BARRIER_FUNCTION_NAME "barrier"
34
RegisterPass<CanonicalizeBarriers> X("barriers",
35
"Barrier canizalization pass");
38
char CanonicalizeBarriers::ID = 0;
41
CanonicalizeBarriers::getAnalysisUsage(AnalysisUsage &AU) const
43
AU.addRequired<LoopInfo>();
44
AU.addPreserved<LoopInfo>();
48
CanonicalizeBarriers::runOnFunction(Function &F)
50
LI = &getAnalysis<LoopInfo>();
52
return ProcessFunction(F);
55
// Canonicalize barriers: ensure all barriers are in a separate BB
56
// containint only the barrier and the terminator, with just one
57
// predecessor and one successor. This allows us to use
58
// those BBs as markers only, they will not be replicated.
60
CanonicalizeBarriers::ProcessFunction(Function &F)
64
InstructionSet PreSplitPoints;
65
InstructionSet PostSplitPoints;
66
InstructionSet BarriersToAdd;
68
CallInst *barrier = NULL;
70
for (Function::iterator i = F.begin(), e = F.end();
73
for (BasicBlock::iterator i = b->begin(), e = b->end();
75
if (CallInst *c = dyn_cast<CallInst>(i)) {
76
if (Function *f = c->getCalledFunction()) {
77
if (f->getName().equals(BARRIER_FUNCTION_NAME)) {
80
// We found a barrier, add the split points.
81
BasicBlock::iterator j = i;
82
PreSplitPoints.insert(j);
83
PostSplitPoints.insert(++j);
85
// Is this barrier inside of a loop?
86
Loop *loop = LI->getLoopFor(b);
88
// We need loops to be canonicalized. If the barrier
89
// is in a loop, add a barrier in the preheader.
90
BasicBlock *preheader = loop->getLoopPreheader();
91
assert(preheader != NULL);
92
Instruction *new_barrier = barrier->clone();
93
new_barrier->insertBefore(preheader->getFirstNonPHI());
95
// No split point after preheader barriers, so we ensure
96
// WI 0,0,0 starts at the loop header. But still we need
98
PreSplitPoints.insert(new_barrier);
100
// Add barriers before any loop backedge. This
101
// is to ensure all workitems run to the end of the loop
102
// (because otherwise first WI will jump back to the
103
// header and other WIs will skip portion of the
105
// We cannot add the barriers directly here to avoid
106
// processing them when going on trough the loop, schedule
107
// them to be added later.
108
BasicBlock *latch = loop->getLoopLatch();
109
assert(latch != NULL);
110
BarriersToAdd.insert(latch->getTerminator());
118
// Add scheduled barriers.
119
for (InstructionSet::iterator i = BarriersToAdd.begin(), e = BarriersToAdd.end();
121
assert(barrier != NULL);
122
Instruction *new_barrier = barrier->clone();
123
new_barrier->insertBefore(*i);
125
BasicBlock::iterator j = new_barrier;
126
PreSplitPoints.insert(j);
127
PostSplitPoints.insert(++j);
130
// Finally add all the split points, now that we are done with the
132
for (InstructionSet::iterator i = PreSplitPoints.begin(), e = PreSplitPoints.end();
134
BasicBlock *b = (*i)->getParent();
135
BasicBlock *new_b = b->splitBasicBlock(*i);
137
b->setName(new_b->getName() + ".prebarrier");
138
Loop *l = LI->getLoopFor(b);
140
l->addBasicBlockToLoop(new_b, LI->getBase());
143
for (InstructionSet::iterator i = PostSplitPoints.begin(), e = PostSplitPoints.end();
145
BasicBlock *b = (*i)->getParent();
146
BasicBlock *new_b = b->splitBasicBlock(*i, b->getName() + ".postbarrier");
147
Loop *l = LI->getLoopFor(b);
149
l->addBasicBlockToLoop(new_b, LI->getBase());
153
LI->verifyAnalysis();